On 10/12/2016 10:40 PM, mikey wrote:
    import std.exception;

    class Worker {
    private:
        uint _wage = 10_000;

    public:
        @property uint wage() { return _wage; }
        @property void wage(uint wage)
        in {
            enforce(wage >= 10_000 && wage <= 1_000_000_000);
        } body {
            _wage = wage;
        }
    }

    class WageSlave : Worker {
    private:
        uint _wage = 10_000;

    public:
        override @property uint wage() { return _wage; }
        override @property void wage(uint wage)
        in {
            enforce(wage >= 10_000 && wage <= 40_000);
        } body {
            _wage = wage;
        }
    }
[...]
    void main() {
[...]
        auto slave = new WageSlave;
        assertThrown( slave.wage = 9_999 );
        assertThrown( slave.wage = 1_000_000_001 );
        assertNotThrown( slave.wage = 10_000 );
        assertNotThrown( slave.wage = 1_000_000_000 ); // BAD - no throw
[...]
    }

The behavior you expect would break substitutability [1]. Consider:

----
void f(Worker w)
{
    w.wage = 50_000; /* Contract of Worker says I can do this. */
}
void main()
{
    f(new Worker); /* Obviously ok. */
f(new WageSlave); /* Must work. A WageSlave object must be usable as a Worker object. */
}
----


[1] https://en.wikipedia.org/wiki/Liskov_substitution_principle

Reply via email to