By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,387 Members | 1,751 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,387 IT Pros & Developers. It's quick & easy.

PHP5 Bug?? extended abstract type enforcement

P: n/a
Hey

I've noticed a somewhat annoying feature in PHP5 when it comes to
extended classes and types.

If I declare an interface and a class that implements it, I get a
"compile" error (read parse error) if I don't actually implement the
interface... expected behaviour.

E.g.

interface MyType
{
function someFunc();
}

class MyClass implements MyType
{

}

Throws the error: Fatal error: Class MyClass contains 1 abstract
methods and must therefore be declared abstract

So I naturally declare MyClass to be abstract (cos I don't want to
implement there for some reason) and everything's fine:

abstract class MyClass implements MyType
{

}

The problem comes when I extend MyClass:

class MyChildClass extends MyClass
{

}

MyType still hasn't been implemented, yet no error is thrown. I do
however get an error when I attempt to instantiate MyExtendedClass:

$c = new MyExtendedClass();

Throws the error: Fatal error: Cannot instantiate abstract class
MyExtendedClass

This forces me to manually check that all my types have been
implemented somewhere along my inheritence hierarchy, which kind of
defeats the point of type enforcement in the first place.

Has anyone else come across this? Does anyone know of any plans to fix
this in the near future?

BTW, PHP5 rocks! Well done to the team.

Cheers,
Rob.
Jul 17 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Rob Long wrote:
MyType still hasn't been implemented, yet no error is thrown. I do
however get an error when I attempt to instantiate MyExtendedClass:

$c = new MyExtendedClass();

Throws the error: Fatal error: Cannot instantiate abstract class
MyExtendedClass

Abstract classes can never be instantiated, only implementations can.
This forces me to manually check that all my types have been
implemented somewhere along my inheritence hierarchy, which kind of
defeats the point of type enforcement in the first place.


The basic concept of interfaces/abstract classes is to provide a prototype
which can be used to create implementations.

If your interface contains methods you don't need, than you are using the
wrong interface, it's as simple as that. When you encounter the problems you
have described, it looks like you have chosen the wrong design for your
needs.
JW


Jul 17 '05 #2

P: n/a
> Abstract classes can never be instantiated, only implementations can.
The basic concept of interfaces/abstract classes is to provide a prototype
which can be used to create implementations. If your interface contains methods you don't need, than you are using the
wrong interface, it's as simple as that. When you encounter the problems you have described, it looks like you have chosen the wrong design for your
needs.


In case anyone else looks at this, JW's answer to the question was basically
perfect --

____________________________________
Wil Moore III, MCP | Integrations Specialist
Jul 17 '05 #3

P: n/a
.oO(Janwillem Borleffs)
Rob Long wrote:
MyType still hasn't been implemented, yet no error is thrown. I do
however get an error when I attempt to instantiate MyExtendedClass:

$c = new MyExtendedClass();

Throws the error: Fatal error: Cannot instantiate abstract class
MyExtendedClass

Abstract classes can never be instantiated, only implementations can.


Question was, why

interface MyType {
function someFunc();
}

class MyClass implements MyType {
}

causes a fatal error at compile time ("Class MyClass contains 1 abstract
methods and must therefore be declared abstract"), but

abstract class MyClass implements MyType {
}

class MyChildClass extends MyClass {
}

doesn't (it complains if you try to instantiate it, but I would also
expect an error like in the first case, looks like PHP doesn't care
about inherited abstract methods).

Micha
Jul 17 '05 #4

P: n/a
<la*******@hotmail.com> wrote in message news:<10*************@corp.supernews.com>...
Abstract classes can never be instantiated, only implementations can.

The basic concept of interfaces/abstract classes is to provide a prototype
which can be used to create implementations.

If your interface contains methods you don't need, than you are using the
wrong interface, it's as simple as that. When you encounter the problems

you
have described, it looks like you have chosen the wrong design for your
needs.


In case anyone else looks at this, JW's answer to the question was basically
perfect --

____________________________________
Wil Moore III, MCP | Integrations Specialist


Err no, JW's answer was basically wrong!

Probably one of the most common techniques used in object-oriented
design is to partially implement an interface in an abstract class,
then derive from that class and implement any remaining functions.

Have either of you used the Vector or ArrayList classes in Java? Well
you might be interested to know that they both derive from
AbstractList, which partially implements the interface List.

I've put a reduced PHP example of this principle here:

interface IList
{
function add($item);
function get($index);
function size();
function isEmpty();
}

abstract class AbstractList implements IList
{
function isEmpty()
{
return $this -> size() == 0;
}
}

class MyList extends AbstractList
{
private $elements = array();

function get($index)
{
return $this -> elements[$index];
}

function add($item)
{
array_push($this -> elements, $item);
}

function size()
{
return count($this -> elements);
}
}

Now what's wrong with this design? Mmm, nothing. AbstractList provides
a skeleton implementation from which I can derive to create my own
lists. This makes my job as a programmer easier. The same thing
applies to basic collections, from which lists are derived.

It would be nice if I could declare in AbstractList the functions I
intend to implement in subclasses as abstract, as is done in Java.
However, if I attempt to do that PHP tells me that I cannot re-define
a function. This is a little annoying, and the feature should be
included in future versions in order to make code more readable, but I
can live with it.

What's wrong with PHP's implementation of type checking? Well,
precisely what I said before: if I fail to implement any of the
functions get(), add() or size() in MyList, then no compile error is
thrown, as type checking on interfaces does not extend into child
classes.

Try the same thing in Java, see what happens.

Is this good for programmers? No, as it forces you to check your types
manually.

PHP knows something is awry when I try this:

$list = new MyList();

throwing an error telling me I cannot instantiate abstract classes,
which is what I'd expect, having not implemented all the functions in
IList. However I shouldn't have to wait until runtime to find this
out.

Everything clear?

Does anyone else have any more sensible comments on the above
behaviour?
Jul 17 '05 #5

P: n/a
Rob Long wrote:
<snip>
class MyList extends AbstractList
{
private $elements = array();

function get($index)
{
return $this -> elements[$index];
}

function add($item)
{
array_push($this -> elements, $item);
}

function size()
{
return count($this -> elements);
}
}
<snip> What's wrong with PHP's implementation of type checking? Well,
precisely what I said before: if I fail to implement any of the
functions get(), add() or size() in MyList, then no compile error is
thrown, as type checking on interfaces does not extend into child
classes.


I think you are seeing the runtime error because PHP assumes (or
automatically decides) that if MyList does not implement all the methods,
then it must be abstract as well.

At least, that's the gist I get from this bug report which complains that
exact methods are not disclosed in the error message:

http://bugs.php.net/bug.php?id=28269

You may want to add your suggestion to that - i.e. that it should be a
compile time error. But then again, I don't know if the original
functionality was intentional or not.
Jul 17 '05 #6

P: n/a
> I think you are seeing the runtime error because PHP assumes (or
automatically decides) that if MyList does not implement all the methods,
then it must be abstract as well.

At least, that's the gist I get from this bug report which complains that
exact methods are not disclosed in the error message:

http://bugs.php.net/bug.php?id=28269

You may want to add your suggestion to that - i.e. that it should be a
compile time error. But then again, I don't know if the original
functionality was intentional or not.


Totally. Isn't it annoying that PHP doesn't demand I declare MyList
abstract though? It does with the parent class AbstractList. I don't
really see how this could be intended behaviour.

So the suggestions for the PHP team:

1. Please can checking on abstract members/classes be enforced right
down an inheritence heirarchy.

2. Please allow the "re-definition" of abstract members in
implementing and child classes; this allows for much more readable
code than at present.

These small (?) changes would bring PHP's OO typing abilities in line
with enterprise languages such as Java. The changes would not affect
the "scripting" programmers that are at the core of PHP's user base,
as we can assume inherited abstract members would not be part of their
remit.
Jul 17 '05 #7

P: n/a
> So the suggestions for the PHP team:

1. Please can checking on abstract members/classes be enforced right
down an inheritence heirarchy.

2. Please allow the "re-definition" of abstract members in
implementing and child classes; this allows for much more readable
code than at present.

These small (?) changes would bring PHP's OO typing abilities in line
with enterprise languages such as Java. The changes would not affect
the "scripting" programmers that are at the core of PHP's user base,
as we can assume inherited abstract members would not be part of their
remit.

Just to let anyone know:

Suggestion 1 has been fixed as of PHP 5.0.2

Suggestion 2 is a feature request which may be incorporated into
future releases, however it takes a lower priority than bug fixing, so
it may be a while.
Jul 17 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.