Hi Marcus,
I think this is really specifying implementation details in an
interface:
interface Coordinate {
public $coord = __get => getCoord, __set => setCoord,
__isset => hasCoord, __unset => delCoord;
public getCoord();
public setCoord($val);
public hasCoord();
public delCoord();
}
This looks to me like the best way to handle this in interfaces:
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 interface
public __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:[EMAIL PROTECTED]
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) <[EMAIL PROTECTED]> wrote:
I think I must be missing something here, but this sounds a
little
tautological - "we can't do it because it doesn't make sense.
This is
because it doesn't make sense"
Certainly most people (myself included) consider interfaces to
be
methods only, but I can't find a reason why not, and a
search-on-wikipedia-instead-of-doing-proper-research appears
to
allow
it:
http://en.wikipedia.org/wiki/Interface_%28computer_science%29
the 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."
-nathan
Best regards,
Marcus
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php