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