Re: Class Properties in Interfaces?
| From: | Jeff Moore | Date: | Tue, 06 May 2008 16:09:31 +0000 |
| Subject: | Re: Class Properties in Interfaces? | ||
| References: | 1 2 3 4 5 6 7 8 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-37499@lists.php.net to get a copy of this message | ||
Hi Marcus,
I think this is really specifying implementation details in an interface:
interface Coordinate { public $coord = __get => getCoord, __set => setCoord,This looks to me like the best way to handle this in interfaces:__isset => hasCoord, __unset => delCoord;public getCoord(); public setCoord($val); public hasCoord(); public delCoord(); }
interface Coord { abstract $coord; }I think this example could be simplified if the basic accessor methods didn't have to be explicitly declared: class MyCoord implements Coordinate { protected $_coord; // actual storage for $coord public $coord = __get => $_coord, __set => setCoord,
__isset => $_coord, __unset => $coord; // Satisfies the interfacepublic __construct($x, $y) {
$this->coord = array($x, $y); // calls setCoord} public setCoord($val) {
if (!is_array($val) || count($val) != 2
|| !is_numeric($val[0]) || !is_numeric($val[1])) {
throw new UnexpectedValueException('Array(x,y) of floats expected');
}
$this->_coord = $val;
}
}
One thing about this syntax is that it give PHP a lot of information to optimize the performance of property access.
Or you could do this
class MyCoord implements Coordinate {
public $coord; // satisfies interface
}
The nice thing about this kind of property is that you can switch between these two implementations over time with out changing how callers use the interface.
Maybe there are some things that could be done with syntax on this:
public $coord = __get => $_coord, __set => setCoord,
__isset => $_coord, __unset => $coord;Can some standard implementation of the __isset and __unset be used to simplify this declaration to something like this? public $coord = __get => $_coord, __set => setCoord; or public $coord __get $_coord __set SetCoord; or to cut down on the underlines... public $coord get $_coord set SetCoord; Additionally, with this syntax, we can allow accessors to have differing visibility, which we cannot do with virtual properties: public $coord get $_coord protected set SetCoord; // Public property with protected setter There are some advantages to this with inheritance, too class Parent { public $foo; } class Child extends Parent { protected $_foo; public $foo get $_foo set SetFoo; function SetFoo($value) { ... } } In this example, a child has added an accessor method to a property defined on a parent without changing the parent. Something you cannot do with virtual properties. I think structural properties would be a useful feature. Best Regards, Jeff On May 6, 2008, at 7:21 AM, Marcus Boerger wrote:
Hello John, the main reason really is storage. If you allow storage in interfaces then you get multiple inheritance with its virtual inheritance (diamond style inheritance) issue. That however onlly applies to plain attributes and not properties which are usually understood as attributes that result in function calls (getter & setter). That said, if PHP had properties, PHP could also allow peroperties in interfaces. So the actual question shoul dbe why we do not support properties. To give an idea how properties could look like: interface Coordinate { public $coord = __get => getCoord, __set => setCoord,__isset => hasCoord, __unset => delCoord;public getCoord(); public setCoord($val); public hasCoord(); public delCoord(); } class MyCoord implements Coordinate { private $_coord = array(0, 0); // actual storage for $coord public __construct($x, $y) { $this->coord = array($x, $y); // calls setCoord } public getCoord() { return $this->_coord; } public setCoord($val) { if (!is_array($val) || count($val) != 2 || !is_numeric($val[0]) || !is_numeric($val[1])) {throw new UnexpectedValueException('Array(x,y) of floats expected');} $this->_coord = $val; } public hasCoord() { return isset($this->_coord[0]) || isset($this->_coord[1]); } public delCoord() { $this->_coord = array(0, 0); } } This tells me two things: a) Pretty damn complex and in that kind of the opposite of PHP's usual KISS approach (Keep It Simple Safe). b) Pretty sexy as it gives a hell lot of control and you can document everything. Check out all the minor details and think of what that would allow. My conclusion is that even it looks sexy, it might be a bit tooooo complex. A much shorter thing to do might be: interface Coord { abstract $coord; } This would just somehow make sure the attribute $this->coord will be accessible as a public attribute in the implementing class. The same rules as for methods would apply. Derick and me discussed solutions around abstract/virtual attributes a lot in the passed. They were all refused however. But what we had in mind also was more about specifying attributes in an abstract way in classes so that they become documentable while being still handled through __get() and friends. marcus Tuesday, April 29, 2008, 5:51:30 PM, you wrote:The article explicitly mentions OOP interfaces in a few languages. But the article, or for that matter any formal definition of an interface isn't really what I asked about: My question was simply: why can't interfaces have properties? John.________________________________From: Nathan Nobbe [mailto:quickshiftin@gmail.com] Sent: 29 April 2008 16:17 To: John Carter -X (johncart - PolicyApp Ltd at Cisco) Cc: internals@lists.php.net Subject: Re: Re: [PHP-DEV] Class Properties in Interfaces?On Tue, Apr 29, 2008 at 6:28 AM, John Carter -X (johncart - PolicyApp Ltd at Cisco) <johncart@cisco.com> wrote:I think I must be missing something here, but this sounds alittletautological - "we can't do it because it doesn't make sense.This isbecause it doesn't make sense"Certainly most people (myself included) consider interfaces tobemethods only, but I can't find a reason why not, and a search-on-wikipedia-instead-of-doing-proper-research appears toallowit:http://en.wikipedia.org/wiki/Interface_%28computer_science%29the problem with that article, as it pertains to this conversation is that it is referring to interfaces as a general concept. 'interfaces' can be formed in many ways, via extension of an abstract class or even an expected set of a parameters in an HTTP request... getting to the more concrete term 'interface' as it pertains to a language keyword, interfaces define a contract; they do not specify implementation details. member variables only facilitate the actions member functions expose and therefore, they are part of the implementation.additionally, one can look to java (and likely others) to see that public attributes are not supported on interfaces. here is a definition from a java5 cert book; "When you create an interface, you're defining a contract for *what* a class can do, without saying anything about how the class will do it. An interface is a contract."-nathanBest regards, Marcus --PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php