Continued looking at properties in D - interfaces and constraints
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Oct 12 14:30:25 PDT 2016
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
More information about the Digitalmars-d-learn
mailing list