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