Is it possible to violate the principle of Liskov substitution in the constructor?

I just installed Microsoft Code contracts. This is part of the .NET Framework and Visual Studio add-ons. It provides performance verification and static verification of certain contracts.

The tool has four warning levels, so I set the highest.

I announced classes designed to violate the Liskov replacement principle.

public class Person
{
    protected int Age { get; set; }

    public Person(int age)
    {
        Contract.Requires(age > 0);
        Contract.Requires(age < 130);
        this.Age = age;
    }
}

public class Child : Person
{
    public Child(int age) : base(age)
    {
        Contract.Requires(age > 0); 
        Contract.Requires(age < Consts.AgeOfMajority);
        Contract.Requires(age < 130);
        this.Age = age;
    }
}

public static class Consts
{
    public readonly static int AgeOfMajority = 18;
}

LSP Status:

if S is a subtype of T, then objects of type T can be replaced by objects of type S without changing any desired properties of this program

In my example, it will be a violation of the assignment: Person person = new Child(23);. We should be able to do this, but we cannot, because children cannot be older than some age, less than what is required by a person's class.

, , CodeContracts: Checked 11 assertions: 11 correct. Code Contracts ?

+4
3

, LSP , , , .

new Child(23);, a Person.

, , S, T.

+15

LSP :

enter image description here

, . , Duck WildDuck:

public abstract class Duck
{
    public abstract string Quack();
    public double Weight { get; set; }

    public Duck(double weight)
    {
        Contract.Requires(weight > 0);
        this.Weight = weight;
    }
}

public class WildDuck : Duck
{
    public WildDuck(double weight)
        : base(weight)
    {
        Contract.Requires(weight > 0);
        this.Weight = weight;
    }

    public override string Quack()
    {
        return "wild quack";
    }
}

ElectricDuck:

public class ElectricDuck : Duck
{
    public Battery Battery { get; set; }

    public override string Quack()
    {
        return "electric quack";
    }

    public ElectricDuck(double weight, Battery battery)
        : base(weight)
    {
        Contract.Requires(weight > 0);
        Contract.Requires(battery != null);
        this.Weight = weight;
        this.Battery = battery;
    }
}

public class Battery
{
    public bool IsEmpty { get; set; }
}

, LSP, ElectricDuck , WildDuck Duck. , ElectricDuck Quack .

ElectricDuck , - LSP:

public void Glow()
{
    Contract.Requires(!this.Battery.IsEmpty);
}

LSP :

public override string Quack()
{
    Contract.Requires(!this.Battery.IsEmpty);
    return "electric quack";
}

CodeContracts .

+6

, . , Child .

, . , .

+2

All Articles