Hi,

On Wed, Oct 31, 2012 at 12:16 AM, Stas Malyshev <smalys...@sugarcrm.com> wrote:
> Hi!
>
>>> I'm not sure why you are expecting this, and also this is probably an
>>> LSP violation, since such override would change semantics of the value
>>> that A clients expect. It may be possible to implement, technically, but
>>> I'm not sure it's the right thing to do.
>>
>> Why would it be not expected and/or a violation of LSP? Accessors
>> impose stricly more restrictions than properties. This code is fine.
>
> You assume accessors are restrictions, but they don't have to be. Consider:
>
> public $foo { get() { return $this->foo;} set($v) { $this->foo_copy =
> $this->foo = $v; } }
>
> You have a postcondition on set() that $this->foo_copy will be the same
> as $this->foo. Override with "public $foo" removes that postcondition.
> But proper inheritance should only strengthen the postconditions, not
> drop them.

Well, LSP is typically not applied to program semantics, since this is
not a generally decidable problem. The only post-conditions that LSP
normally enforces is type based, i.e. the covariance of the return
type.

Instead, LSP simply states that, given B <: A, all objects of A can be
substituted by objects of B while preserving the validity of the
method calls on these objects, and the validity of their return
values. This is guaranteed here:

a get accessor will return a value of type any when performing
$a->foo, so does a property. LSP checks.
a set accessor takes a argument, so does $a->foo = "..". LSP checks.

My point is: all valid usages of accessors will also be valid when the
subclass overrides them using a normal property.

>
>> Just like it is fine in theory to have interface A { public $foo {
>> get(); set($v); } } class B implements A { public $foo; }
>
> That's different. In this case, you say "I will have some property
> $foo", without promising anything about it. But specific code can
> actually make some promises about $foo, and you can violate these
> promises by overriding it with public $foo.

That's the same argument as before. Corresponding to LSP it only gives
very specific promises, that are simply type based and not the actual
strongest post-condition.

> Interface does not impose
> any conditions except that $foo exist and is gettable/settable. Specific
> getters/setters can impose much more involved conditions, which "public
> $foo" may not be able to satisfy.

Following your argument:

class A { public $v = 1; public foo() { $this->v = 2; } } class B
extends A {public foo() { $this->v = 4; }}

B should violate LSP, since the postcondition of B::foo() does not
imply postcondition of A::foo(). This is obviously not correct: this
code is fine.

Best,

>
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227



-- 
Etienne Kneuss
http://www.colder.ch

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to