Re: parent_ctor()
| From: | Kristian Koehntopp | Date: | Tue, 18 Jul 2000 17:36:56 +0000 |
| Subject: | Re: parent_ctor() | ||
| References: | 1 2 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-24996@lists.php.net to get a copy of this message | ||
Stanislav Malyshev wrote:
> KK>> Agreed, settype() should not be needed in a clean design. It
> KK>> is useful in purposely unclean designs, though. Specifically,
>
> I don't really want to be useful in bad design. Also, please define what
> you want - a tool to do everything or a tool to do good OO? First you bash
> PHP because it's OO is not clean enough and then you propose method to
> defy any OO at all. If you need typeless data collections, hashes are at
> your service. If you need typed data-code bounds, go classes - but they
> are _typed_, you can just turn around halfway and say "now I want it to
> be typeless again". That's what I call a messy design.
Slow, please. First: I do not propose the use of settype() to
change the class of an object as a standard method. It is needed
in few, very special circumstances.
Second: The meaning of "type" is somewhat different in
dynamically typed languages than in statically typed languages,
I believe. I might err here, as I am weak in C++, so please
correct me.
If I understood the little C++ I know correctly, in C++ the type
of an object pointed to is defined by the type of the pointer
and not a property of the object. That is, if I have "class B
extends A", and I have
A *a = new B;
this is valid C++ because B is a subclass of A. But as a is of
type (A *), I can only use instance variables and methods of A
on a, despite the fact that a is actually a B (which happens to
be an A as well). This is, because C++ tries to determine the
validity of all method calls at compile time and not at run-time
and so it cannot look at the object in question and determine
its real capabilities.
In dynamically typed languages, these determination is made
later, at run-time, and an object will always know its
type/class and that will (almost) never change. That is, in
Objective-C, in Smalltalk, and in PHP, when you do
$a = new B;
$a will always be treated as an instance of B and you will
always have access to all instance variables and methods of B.
Even if you followed a (void *)a in Objective-C and the thing at
the end of that pointer could be identified as an Object, you'd
be able to tell it's class, it's instance variable names and
types, and the names and signatures of all it's methods because
these are properties of the object itself, and not the object
pointer.
Because of this, you will see much less casts and dynamic casts
(downcasts? the <>-thingie in C++) in dynamically typed
languages. The objects just know what they are and you do not
need to change their type.
That's why you (almost) never need settype() in such languages.
> KK>> it is useful in designs where one class must pose as another
> KK>> class, or any class (the RPC proxy example I keep coming back
> KK>> to).
>
> I do not see what you mean. Why any class should pose as any other class,
> especially in PHP?
If you look at objects from the statically typed POV, you see
your objects in an aristocratic way: You are what you are by
birth and it is important who your parents were. Very english.
In dynamically types languages it can be useful to look at
objects from a different, more "democratic" angle: It is not
important who your parents were, but what you can do, that is,
which instance variables and methods you implement. That is, I
do not really care what the class of an object is as long as the
methods I want to call are present. Very american.
Now consider the delegate mechanism I began to outline. With
such a mechanism done right you could implement a generic class,
that is, a class that implements no instance variable or method
for real, but potentially claiming to implement everything
(probably with checking some constraints previously, see below).
For what can this be useful?
One application that is useful for (there are others, and they
are of a similarly "generic" or "esotheric" caliber) is the
generic RPC proxy. Consider some kind of request broker which
offers several services published by some servers in your
network, an ORB for example. You want to be able to use these
services from PHP, but without the complexity of RPC at all. You
simple want to call a local method of a local object, and the
local object shall take care of all the special handling for
RPC.
Using a delegate mechanism you can write a generic RPC class,
which asks the request broker for the names and signatures of
the published objects, and which implements the appropriate
argument marshalling et al. This proxy class would implement all
the methods of the class it proxies for, and since it implements
all this, it factually _is_ such a class (it is in fact the
local proxy for a remote instance of that class) and can safely
settype() itself. No need to write stub code, in fact no coding
at all, and still you get native PHP object syntax and the
proper class.
I admit that this is very advanced use, and it is not really
crucial at all except for these cases. It is a good
illustration, though, to show how a good object model can be
used to very elegantly solve complex problems. It is also a good
example to show the difference between dynamic and static types
(Try it in C++, if you like. I bet you can do it in C++ 3.0, but
nobody will be able to read and understand it 1/2 :-).
Kristian
--
Kristian Köhntopp, NetUSE AG Siemenswall, D-24107 Kiel
Tel: +49 431 386 436 00, Fax: +49 431 386 435 99
Using PHP3? See our web development library at http://phplib.netuse.de/