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

Using a Resource as a Class Property

P: n/a
I'm wondering if I'm doing this right, as far as using another class
object as a PHP class property.

class my_baseclass {
var $Database;
var $ErrorMessage;
var $TableName;
var $RecordSet;
function my_baseclass(){
$this->TableName = "";
$this->RecordSet = array();
$this->Database = new my_database();
$this->ErrorMessage = $this->Database->ErrorMessage;
return true;
}
}

It seems to be working, but this kinds stuff skirts the edge of my PHP
grok, so I dunno.
Jul 21 '07 #1
Share this Question
Share on Google+
61 Replies


P: n/a
..oO(Sanders Kaufman)
>I'm wondering if I'm doing this right, as far as using another class
object as a PHP class property.

class my_baseclass {
var $Database;
var $ErrorMessage;
var $TableName;
var $RecordSet;
function my_baseclass(){
$this->TableName = "";
$this->RecordSet = array();
$this->Database = new my_database();
$this->ErrorMessage = $this->Database->ErrorMessage;
return true;
}
}

It seems to be working, but this kinds stuff skirts the edge of my PHP
grok, so I dunno.
Using one object "inside" another is called an aggregation and a very
common and important concept in OOP.

But if you want to dive into that, I would strongly recommend to upgrade
to PHP 5 and make use of its OOP features.

Micha
Jul 21 '07 #2

P: n/a
Michael Fesser wrote:
.oO(Sanders Kaufman)
>I'm wondering if I'm doing this right, as far as using another class
object as a PHP class property.

class my_baseclass {
var $Database;
var $ErrorMessage;
var $TableName;
var $RecordSet;
function my_baseclass(){
$this->TableName = "";
$this->RecordSet = array();
$this->Database = new my_database();
$this->ErrorMessage = $this->Database->ErrorMessage;
return true;
}
}

It seems to be working, but this kinds stuff skirts the edge of my PHP
grok, so I dunno.

Using one object "inside" another is called an aggregation and a very
common and important concept in OOP.
So I'm doing it right?! Cool. I know there are some cases where you're
supposed to serialize objects instead of... what am I doing, passing by
reference? Instantiating?

But if you want to dive into that, I would strongly recommend to upgrade
to PHP 5 and make use of its OOP features.
I soooooo want to do this in 5... but that won't be an option until like
October. Until then, it's gotta work on 4.
Jul 21 '07 #3

P: n/a
..oO(Sanders Kaufman)
>So I'm doing it right?! Cool.
It always depends on what you want to achieve. From just looking at the
posted snippet and without knowing what the my_baseclass is supposed to
do, it's hard to tell whether you're doing it right or not, since the
code is not doing anything useful, except for initializing some member
variables.
>I know there are some cases where you're
supposed to serialize objects instead of... what am I doing, passing by
reference? Instantiating?
Aggregating. ;) You create an instance of a class, which is used inside
another object. That's it (in this case).

Serializing can be used if you want to store an object to a file or a
database.

Micha
Jul 21 '07 #4

P: n/a
Sanders Kaufman wrote:
function CreateTable($sTableName, $sTableDef){
//Returns true, or false with an ErrorMessage.
//Prefixes table name and appends ISAM engine type.
//Auto-creates id field, but user should still provide a unique
field
$bRetVal = true;
$this->RecordSQL = "CREATE TABLE {$this->TablePrefix}_$sTableName
(id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id),
$sTableDef) ENGINE=MyISAM";
if(!$this->RunSQL($this->RecordSQL)){
$bRetVal = false;
$this->ErrorMessage=mysql_error();
} else {
$this->ErrorMessage="OK";
}
return $bRetVal;
}

This is actually one of the parts of my architecture I'm most proud of.
By specifying a table prefix in the class, it allows multiple web
applications to all use the same database, without any problem with same
names.

For example, suppose you use this framework to build a discussion forum
program. A client then uses it to build to web sites that use the same
database server (e.g. kaiser.kaufman.net and caesar.kaufman.net, both
using mysql.kaufman.net).

If the discussion forum uses a "users" table, then the developer can
isolate one from the other by specifying a unite table prefix.
Jul 21 '07 #5

P: n/a
Sanders Kaufman wrote:
class bvckvs_database
You seem to have re-invented PDO/MDB2.

http://en.wikipedia.org/wiki/Reinventing_the_wheel

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 31 days, 5:12.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 22 '07 #6

P: n/a
Sanders Kaufman wrote:
If the discussion forum uses a "users" table, then the developer can
isolate one from the other by specifying a unite table prefix.
Yep -- it's a fairly common construct. It's arguably better to use
schemas, but not all RDBMSs have very good support for that.

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 31 days, 5:16.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 22 '07 #7

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>class bvckvs_database

You seem to have re-invented PDO/MDB2.

http://en.wikipedia.org/wiki/Reinventing_the_wheel
They say that everything that will ever be written, has already been
written.
Jul 22 '07 #8

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>If the discussion forum uses a "users" table, then the developer can
isolate one from the other by specifying a unite table prefix.

Yep -- it's a fairly common construct. It's arguably better to use
schemas, but not all RDBMSs have very good support for that.
Really? Common, eh? I guess I should shelve my ideas for velcro and
the frisbee, as well.

But yeah - DBMS portability was a core design concept.
Jul 22 '07 #9

P: n/a
Michael Fesser wrote:
.oO(Sanders Kaufman)
class my_childclass extends my_baseclass {
function my_childclass() {
// first call parent constructor or we won't have a database ...
parent::my_baseclass();
// then do some other stuff
...

OK - that seems to be where I went wrong. I thought the base class's
constructor was automatically called when the extended class's was.

So, bottom line, what you're saying here is that when you extend a base
class like this, you still have to manually call the base class's
constructor? Zat right?
Jul 22 '07 #10

P: n/a
..oO(Sanders Kaufman)
>OK - that seems to be where I went wrong. I thought the base class's
constructor was automatically called when the extended class's was.
Nope.
>So, bottom line, what you're saying here is that when you extend a base
class like this, you still have to manually call the base class's
constructor? Zat right?
Correct. PHP doesn't do that automatically, except if the child class
doesn't have a constructor. Then PHP will call the one from the base
class, if it exists. But as soon as your child class uses its own
constructor, you have to manually call the parent one. Usually this
should be the first action.

In PHP 4 you have to use the name of the base class for that (if I
remember that correctly ;-), haven't used PHP 4 since years):

class TFoo extends TBar {
function TFoo {
parent::TBar();
...
}
}

In PHP 5 all constructors have the same name, so it would be just:

class TFoo extends TBar {
public function __construct() {
parent::__construct();
...
}
}

Micha
Jul 22 '07 #11

P: n/a
Michael Fesser wrote:
.oO(Sanders Kaufman)
>So, bottom line, what you're saying here is that when you extend a base
class like this, you still have to manually call the base class's
constructor? Zat right?

Correct. PHP doesn't do that automatically, except if the child class
doesn't have a constructor. Then PHP will call the one from the base
class, if it exists. But as soon as your child class uses its own
constructor, you have to manually call the parent one. Usually this
should be the first action.
Got it - and I wish I'd got it a year ago!

Is that a normal OOP way to do it - done that way in C++ and whatnot -
or is this unique to PHP?

Jul 23 '07 #12

P: n/a
..oO(Sanders Kaufman)
>Michael Fesser wrote:
>>
Correct. PHP doesn't do that automatically, except if the child class
doesn't have a constructor. Then PHP will call the one from the base
class, if it exists. But as soon as your child class uses its own
constructor, you have to manually call the parent one. Usually this
should be the first action.

Got it - and I wish I'd got it a year ago!

Is that a normal OOP way to do it - done that way in C++ and whatnot -
or is this unique to PHP?
It works like that in all languages I know and it simply _has_ to work
that way. The programmer has to be able to exactly define if and when a
parent method will be called. Just consider this little example:

class A {
protected $data = NULL;

public function __construct() {
$this->doSomething();
}

private function doSomething() {
// do something with $this->data
}
}

class B extends A {
public function __construct() {
$this->data = 'foo';
parent::__construct();
}
}

Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

Micha
Jul 23 '07 #13

P: n/a
Michael Fesser wrote:
.oO(Sanders Kaufman)
>Michael Fesser wrote:
>>Correct. PHP doesn't do that automatically, except if the child class
doesn't have a constructor. Then PHP will call the one from the base
class, if it exists. But as soon as your child class uses its own
constructor, you have to manually call the parent one. Usually this
should be the first action.
Got it - and I wish I'd got it a year ago!

Is that a normal OOP way to do it - done that way in C++ and whatnot -
or is this unique to PHP?

It works like that in all languages I know and it simply _has_ to work
that way. The programmer has to be able to exactly define if and when a
parent method will be called. Just consider this little example:

class A {
protected $data = NULL;

public function __construct() {
$this->doSomething();
}

private function doSomething() {
// do something with $this->data
}
}

class B extends A {
public function __construct() {
$this->data = 'foo';
parent::__construct();
}
}

Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

Micha
Micha,

Generally unique to PHP. Java, C++ and SmallTalk all call the base
class constructor automatically before any code is executed in the child
class constructor.

Also, the parent should never have a dependency on the child class, and
the parent's class constructor should never depend on anything in the
child class other than what is passed to the constructor.

Your case is improper OO. What if an instance of A is created instead
of B? It wouldn't work.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #14

P: n/a
..oO(Jerry Stuckle)
>Michael Fesser wrote:
>Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

Generally unique to PHP.
Not entirely.
>Java, C++ and SmallTalk all call the base
class constructor automatically before any code is executed in the child
class constructor.
It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.
>Also, the parent should never have a dependency on the child class, and
the parent's class constructor should never depend on anything in the
child class other than what is passed to the constructor.
Correct, and I don't think this is an issue here. The parent will work
either way. OK, the same thing, slightly modified:

class A {
protected $data = NULL;

public function __construct() {
$this->initData();
$this->doSomething();
}

protected function initData() {
}

private function doSomething() {
// do something with $this->data
}
}

class B extends A {
public function __construct() { // could be removed now
parent::__construct();
}

protected function initData() {
parent::initData();
$this->data = 'foo';
}
}

The result is the same.
>Your case is improper OO. What if an instance of A is created instead
of B? It wouldn't work.
It would. A::doSomething() just has to check if $this->data is empty and
react accordingly.

While this example was rather abstract, I use something similar in my
own web framework, for example in my form handling components. The base
class of my form controls accepts an ID, a caption and a default value
in its constructor. One of the derived classes performs a special check
on the passed default value before calling the inherited constructor. Of
course I could write this in a different way, but in this special case
calling the parent constructor a bit later is a really handy feature.

Micha
Jul 23 '07 #15

P: n/a
Michael Fesser wrote:
Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.
So extended (child?) classes MUST NOT (for OOP reasons) automatically
call a constructor. Rather, it should be called manually, if and when
it's desired.

And this is not unique to PHP.

Zat right?

(Scuse me if I'm being dense, but I got some head stuff going on.)
Jul 23 '07 #16

P: n/a
Jerry Stuckle wrote:
Michael Fesser wrote:
>Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

Generally unique to PHP. Java, C++ and SmallTalk all call the base
class constructor automatically before any code is executed in the child
class constructor.

OK - to update my understanding...
PHP doesn't automatically call constructors BUT doing so would be more
in keeping with the Tao of OOP.

Zat right?

Also, the parent should never have a dependency on the child class, and
the parent's class constructor should never depend on anything in the
child class other than what is passed to the constructor.
Wow. Cool. When I built my classes, I didn't KNOW it should be done
that way, but it FELT right.

I seriously considered writing the classes in a way to where the parent
would *presume* all kinds of stuff about the child, but it didn't jibe
with my obsession with atomicity - so I didn't do it.
Jul 23 '07 #17

P: n/a
Michael Fesser wrote:
It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.
That's a real hum-dinger for both OOP and SQL. It seems that commercial
vendors never seem to stick with the academic imperatives. I don't mind
when they ADD stuff, but it sucks when they CHANGE stuff.
Jul 23 '07 #18

P: n/a
Sanders Kaufman wrote:
So extended (child?) classes MUST NOT (for OOP reasons) automatically
call a constructor. Rather, it should be called manually, if and when
it's desired.
s/MUST NOT/DO NOT/

Of course, if you don't define a __construct() method in the child
class, the parent class' constructor will get called automatically.

Basically, in PHP __construct() behaves the same way other methods
do: if you define the method in a child class, the parent class'
method will be ignored, unless you explicitly call it from within
the child class' method (using "parent::method()").

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 32 days, 12:11.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 23 '07 #19

P: n/a
Michael Fesser wrote:
.oO(Jerry Stuckle)
>Michael Fesser wrote:
>>Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.
Generally unique to PHP.

Not entirely.
>Java, C++ and SmallTalk all call the base
class constructor automatically before any code is executed in the child
class constructor.

It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.
Object Pascal is not a true OO language. It's an OO extension to a
structured language (and not a real good implementation at that - there
are several holes in the way it is implemented). The ones I mentioned
are true OO languages.
>Also, the parent should never have a dependency on the child class, and
the parent's class constructor should never depend on anything in the
child class other than what is passed to the constructor.

Correct, and I don't think this is an issue here. The parent will work
either way. OK, the same thing, slightly modified:

class A {
protected $data = NULL;

public function __construct() {
$this->initData();
$this->doSomething();
}

protected function initData() {
}

private function doSomething() {
// do something with $this->data
}
}

class B extends A {
public function __construct() { // could be removed now
parent::__construct();
}

protected function initData() {
parent::initData();
$this->data = 'foo';
}
}

The result is the same.
>Your case is improper OO. What if an instance of A is created instead
of B? It wouldn't work.

It would. A::doSomething() just has to check if $this->data is empty and
react accordingly.
No, Micha, it is improper OO. The base class is depending on something
form the derived class. Additionally, in proper OO, A::data would be
private to the base class. And the constructor for A would be called
before the constructor to B ever got started.

That is a proper OO implementation, and follows OO theory and operations.
While this example was rather abstract, I use something similar in my
own web framework, for example in my form handling components. The base
class of my form controls accepts an ID, a caption and a default value
in its constructor. One of the derived classes performs a special check
on the passed default value before calling the inherited constructor. Of
course I could write this in a different way, but in this special case
calling the parent constructor a bit later is a really handy feature.

Micha
You should work on your OO techniques more. It ends up causing more
problems than it solves.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #20

P: n/a
Sanders Kaufman wrote:
Jerry Stuckle wrote:
>Michael Fesser wrote:
>>Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

Generally unique to PHP. Java, C++ and SmallTalk all call the base
class constructor automatically before any code is executed in the
child class constructor.


OK - to update my understanding...
PHP doesn't automatically call constructors BUT doing so would be more
in keeping with the Tao of OOP.

Zat right?
That is true. And perhaps one day PHP will more closely follow the OO
way of doing things. They've been getting closer with each release.
>
>Also, the parent should never have a dependency on the child class,
and the parent's class constructor should never depend on anything in
the child class other than what is passed to the constructor.

Wow. Cool. When I built my classes, I didn't KNOW it should be done
that way, but it FELT right.

I seriously considered writing the classes in a way to where the parent
would *presume* all kinds of stuff about the child, but it didn't jibe
with my obsession with atomicity - so I didn't do it.
The child class defines the derivation, and therefore knows it has a
parent class (and some things about that parent). However, the parent
doesn't know if (or when) it is being used as a base class, so it should
never assume things which may or may not be there (or set).

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #21

P: n/a
Sanders Kaufman wrote:
Michael Fesser wrote:
>Quite simple: A base class with a member variable and a method that
performs some action with that. Since this is done in the constructor,
every child class has to be able to initialize the data before calling
the parent constructor, as you can see in B::__construct(). If PHP would
automatically call the parent constructor, this would be impossible.

So extended (child?) classes MUST NOT (for OOP reasons) automatically
call a constructor. Rather, it should be called manually, if and when
it's desired.
Incorrect in OO theory, but used in some applications.
>
And this is not unique to PHP.
True, there are some other implementations which implement part of the
OO world, but not all.
Zat right?

(Scuse me if I'm being dense, but I got some head stuff going on.)

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #22

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>So extended (child?) classes MUST NOT (for OOP reasons) automatically
call a constructor. Rather, it should be called manually, if and when
it's desired.

s/MUST NOT/DO NOT/

Of course, if you don't define a __construct() method in the child
class, the parent class' constructor will get called automatically.

Basically, in PHP __construct() behaves the same way other methods
do: if you define the method in a child class, the parent class'
method will be ignored, unless you explicitly call it from within
the child class' method (using "parent::method()").
So to correct my statement:

In OOP (not just PHP) the constructor of the grandest child :) will be
called when a class is instantiated as an object.

Zat right?

Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?
Jul 23 '07 #23

P: n/a
Jerry Stuckle wrote:
Michael Fesser wrote:
>It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.

Object Pascal is not a true OO language. It's an OO extension to a
structured language (and not a real good implementation at that - there
are several holes in the way it is implemented). The ones I mentioned
are true OO languages.
I may be getting too far out of scope here, but I seem to recall some
PHP guys getting all uppity about PHP not being true to OOP. Is there
anything to that, and if so, is it significant?

Of course - I may be thinking of waaay back when PHP stood for "Personal
Homepage Processor".
No, Micha, it is improper OO. The base class is depending on something
form the derived class. Additionally, in proper OO, A::data would be
private to the base class. And the constructor for A would be called
before the constructor to B ever got started.
I gotta say, even in my sophomoric understanding - that just makes good
sense.

OOP lives and dies on compartmentalization. If you build two
interdependent classes, then neither one can ever be an object unto
itself. That may be class-oriented, but it darn sure ain't object-oriented.
Jul 23 '07 #24

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>I seriously considered writing the classes in a way to where the
parent would *presume* all kinds of stuff about the child, but it
didn't jibe with my obsession with atomicity - so I didn't do it.

The child class defines the derivation, and therefore knows it has a
parent class (and some things about that parent). However, the parent
doesn't know if (or when) it is being used as a base class, so it should
never assume things which may or may not be there (or set).
So - it's okay in the purist of OOP to have a child that presumes things
about the parent, but not t'other way 'round?

That makes a little better sense. I was kinda beginning to wonder what
use there was to having a child that couldn't (or shouldn't) talk to its
parent.

All of my classes talk with their parents, and I was thinking I might be
doing something non-OOP there.

Parent. Parents. Hmmm. That takes me to a new question - I understand
that a PHP class be an extension of more than one parent class.
(e.g. "class myClass extends oMommy, oDaddy") Are there any common
pitfalls y'all wanna warn me about before I start adding that way to my
mind's toolbox?

I haven't started doing it that way yet because I've only just started
doing OOP in PHP... but it stands to reason that I likely will, and soon.
Jul 23 '07 #25

P: n/a
Sanders Kaufman wrote:
Parent. Parents. Hmmm. That takes me to a new question - I understand
that a PHP class be an extension of more than one parent class.
(e.g. "class myClass extends oMommy, oDaddy")
You understand differently to me then. This is called "multiple
inheritance" and very few OO languages support it.

You can inherit from more than one class like this:

class A {}
class B extends A {}
class C extends B {} /* and thus A */

but not like this:

class A {}
class B {}
class C extends A, B {}

If you use interfaces, you can write a class that implements multiple
interfaces:

interface A {}
interface B {}
class A implements A, B {}

and that is fine. (Same story with Java.)

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 32 days, 18:20.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 23 '07 #26

P: n/a
Sanders Kaufman wrote:
Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?
I didn't say that, no.

<?php
/* Aggragation */
class A {}
class B
{
public $a = new A;
}
?>

<?php
/* Inheritance */
class A {}
class B extends A {}
?>

<?php
/* Implementation */
interface A {}
class B implements A {}
?>

<?php
/* Instantiation */
class A {}
$a = new A;
?>

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 32 days, 18:28.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 23 '07 #27

P: n/a
Sanders Kaufman wrote:
Toby A Inkster wrote:
So to correct my statement:

In OOP (not just PHP) the constructor of the grandest child :) will be
called when a class is instantiated as an object.
Wow, now that I've done it that way, I can see why it's the better way.
By having to call the parent constructor from within the child object,
It gives the child better control.

For example, my parent has a "database" object, and a built-in default
way of talking to it; while the child has another way of talking to it -
each established in the constructor, and each running a verification
process to ensure it still works

So now I can have the child set the values for the conversation before
the parent .... blah, blah, blah.

Bottom line - I talk to the DBMS once, instead of twice during
initialization.

Cool.
Thanks.

>
Zat right?

Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?

Jul 23 '07 #28

P: n/a
Toby A Inkster wrote:
If you use interfaces, you can write a class that implements multiple
interfaces:

interface A {}
interface B {}
class A implements A, B {}
Interfaces - is that a PHP5 thing?
I don't think I've seen anything about it in 4.
I'm stuck in 4 until late this year.
Jul 23 '07 #29

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?

I didn't say that, no.

<?php
/* Aggragation */
class A {}
class B
{
public $a = new A;
}
?>

<?php
/* Inheritance */
class A {}
class B extends A {}
?>

<?php
/* Implementation */
interface A {}
class B implements A {}
?>

<?php
/* Instantiation */
class A {}
$a = new A;
?>
OK = but what is it called when you use "extend" to create a child class?
Jul 23 '07 #30

P: n/a
Sanders Kaufman wrote:
Jerry Stuckle wrote:
>Sanders Kaufman wrote:
>>I seriously considered writing the classes in a way to where the
parent would *presume* all kinds of stuff about the child, but it
didn't jibe with my obsession with atomicity - so I didn't do it.

The child class defines the derivation, and therefore knows it has a
parent class (and some things about that parent). However, the parent
doesn't know if (or when) it is being used as a base class, so it
should never assume things which may or may not be there (or set).

So - it's okay in the purist of OOP to have a child that presumes things
about the parent, but not t'other way 'round?
Not just a purist. Its the way things HAVE to be.

The child always has a parent (and what that parent is). But the parent
may or may not have children, and never knows one way or the other. And
if it does have children, it doesn't know what those children might be.
That makes a little better sense. I was kinda beginning to wonder what
use there was to having a child that couldn't (or shouldn't) talk to its
parent.

All of my classes talk with their parents, and I was thinking I might be
doing something non-OOP there.
Nope, that's part of what makes OO so powerful.
Parent. Parents. Hmmm. That takes me to a new question - I understand
that a PHP class be an extension of more than one parent class.
(e.g. "class myClass extends oMommy, oDaddy") Are there any common
pitfalls y'all wanna warn me about before I start adding that way to my
mind's toolbox?

I haven't started doing it that way yet because I've only just started
doing OOP in PHP... but it stands to reason that I likely will, and soon.

There's a lot PHP doesn't have yet. But it's getting closer. PHP 5 is
a step in the right direction, and PHP 6 will be even more so.


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #31

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>Parent. Parents. Hmmm. That takes me to a new question - I understand
that a PHP class be an extension of more than one parent class.
(e.g. "class myClass extends oMommy, oDaddy")

You understand differently to me then. This is called "multiple
inheritance" and very few OO languages support it.

You can inherit from more than one class like this:

class A {}
class B extends A {}
class C extends B {} /* and thus A */

but not like this:

class A {}
class B {}
class C extends A, B {}

If you use interfaces, you can write a class that implements multiple
interfaces:

interface A {}
interface B {}
class A implements A, B {}

and that is fine. (Same story with Java.)
Very true. And it can be good or bad. In some ways I miss multiple
inheritance, but in other ways, not. I've seen it misused more than
properly used.

For instance, I taught a C++ course (not written by me) at one time
which used the example "toy car" as inheriting from both toy and car.
Now I agree it is a toy - but it is not a car in the same sense a real
car is. But it was an example I had to teach :-(.

I've seen very few true implementations of multiple inheritance, and
those I have seen have basically been implementations of a base class
plus one or more interfaces.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #32

P: n/a
Sanders Kaufman wrote:
Toby A Inkster wrote:
>Sanders Kaufman wrote:
>>So extended (child?) classes MUST NOT (for OOP reasons) automatically
call a constructor. Rather, it should be called manually, if and
when it's desired.

s/MUST NOT/DO NOT/

Of course, if you don't define a __construct() method in the child
class, the parent class' constructor will get called automatically.

Basically, in PHP __construct() behaves the same way other methods
do: if you define the method in a child class, the parent class'
method will be ignored, unless you explicitly call it from within
the child class' method (using "parent::method()").

So to correct my statement:

In OOP (not just PHP) the constructor of the grandest child :) will be
called when a class is instantiated as an object.
True. And in true OO languages, the parent constructor(s) is(are)
called, also.
Zat right?

Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?

Inheritance.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #33

P: n/a
Sanders Kaufman wrote:
Sanders Kaufman wrote:
>Toby A Inkster wrote:
>So to correct my statement:

In OOP (not just PHP) the constructor of the grandest child :) will be
called when a class is instantiated as an object.

Wow, now that I've done it that way, I can see why it's the better way.
By having to call the parent constructor from within the child object,
It gives the child better control.

For example, my parent has a "database" object, and a built-in default
way of talking to it; while the child has another way of talking to it -
each established in the constructor, and each running a verification
process to ensure it still works
Probably an incorrect implementation of OO, depending on exactly what
you're trying to do.

The purpose of OO is to allow the child object to use the parent
object's methods (functions) and to not have to write its own.

In the case of a Database object, the main purpose of the object is to
perform the communications. Another class which does it a different way
would be a different class.

Now that doesn't mean you shouldn't have a database object which doesn't
have children. For instance, as a simple example, you might have:

class Database
member database name
abstract methods open (connect), close (disconnect), query

class MySQL_Database extends Database
methods open, close, query

class PostGres_Database extends Database
methods open, close query

But you should not have:

class MySQL_Database
member database name
methods open, close, query

class PostGres_Database extends MySQL_Database
methods open, close query (which override MySQL Database)

I know this isn't exactly what you're saying - but I wanted to make it
more extreme to be more obvious.

If you're basically creating a MySQL_Database class then overriding most
of the methods in the child class, you should look at whether your
design is appropriate or not. In most cases I would argue it would not
be. But you could have a third class as the parent with the appropriate
shared methods, and two other classes derived from the original parent.

That's not to say overriding is *never* appropriate - in many cases it
is. But as part of the overriding, you generally end up calling the
parent class method, also.
So now I can have the child set the values for the conversation before
the parent .... blah, blah, blah.

Bottom line - I talk to the DBMS once, instead of twice during
initialization.

Cool.
Thanks.

==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #34

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>So - it's okay in the purist of OOP to have a child that presumes
things about the parent, but not t'other way 'round?

Not just a purist. Its the way things HAVE to be.
That's what I meant.
I was using "purist" in it's adjective form, not noun - as in, "the most
pure".

Jul 23 '07 #35

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?

Inheritance.
And then... overwriting functions would be polymorph?
And... PHP allows function overwriting?

Zat right?
Jul 23 '07 #36

P: n/a
..oO(Jerry Stuckle)
>Michael Fesser wrote:
>>
It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.

Object Pascal is not a true OO language. It's an OO extension to a
structured language (and not a real good implementation at that - there
are several holes in the way it is implemented). The ones I mentioned
are true OO languages.
Depends on how you define "true OO language". Many people don't even see
Java as a true OO language (mainly because of the scalar types IIRC).
And when comparing C++ and Delphi, I clearly prefer the latter, its
object model has some really nice and handy features (properties with
read-only or write-only access for example, I like that).

After all it all comes down to how strictly you want to follow a
paradigm. It doesn't really matter if we're talking about OOP or MVC for
example. Some people prefer to follow the rules as strictly as possible,
but for me that would cause more troubles than it would solve. Sometimes
you simply have to think more practical than theoretical.
>It would. A::doSomething() just has to check if $this->data is empty and
react accordingly.

No, Micha, it is improper OO. The base class is depending on something
form the derived class.
I still don't see it this way. The derived class just performs a
different initialization of the data. The base class will still work
with or without that, because it already has this method ifself. It's
just overwritten by the child classes as necessary. I could even have
declared A::doSomething() as abstract, so child classes would be forced
to overwrite/implement it.

It's not always possible to initialize an object just by passing all the
required data to the constructor, sometimes you have to perform
additional task in separate methods. That's not a problem. And calling a
child's method from a parent's method is not only allowed, but very
common and important (virtual methods, polymorphism, things like that).
Additionally, in proper OO, A::data would be
private to the base class.
Sure, can be done. But I prefer to declare my properties as protected,
if they are supposed to be accessed in derived classes. I don't want to
write getters and setters for every single member variable. While it
would be "true OO", it's usually too much work for nothing. Things are a
bit different when properties should be accessible from the outside, but
even then I sometimes simply declare them as public.
>And the constructor for A would be called
before the constructor to B ever got started.
Could be done easily in the modified version of my example.

Micha
Jul 23 '07 #37

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>Wow, now that I've done it that way, I can see why it's the better way.
By having to call the parent constructor from within the child object,
It gives the child better control.

For example, my parent has a "database" object, and a built-in default
way of talking to it; while the child has another way of talking to it
- each established in the constructor, and each running a verification
process to ensure it still works

Probably an incorrect implementation of OO, depending on exactly what
you're trying to do.

The purpose of OO is to allow the child object to use the parent
object's methods (functions) and to not have to write its own.

In the case of a Database object, the main purpose of the object is to
perform the communications. Another class which does it a different way
would be a different class.

I probably used the phrase "different way" poorly.

What I mean is that my database class, by default, connects to my
primary database server. But other classes in my architecture,
extending that one, may need to contact a different server.

So, by having the child modify the parent connection parameters, it can
talk to whoever it needs to... not just my primary.
Now that doesn't mean you shouldn't have a database object which doesn't
have children. For instance, as a simple example, you might have:

class Database
member database name
abstract methods open (connect), close (disconnect), query

class MySQL_Database extends Database
methods open, close, query

class PostGres_Database extends Database
methods open, close query

But you should not have:

class MySQL_Database
member database name
methods open, close, query

class PostGres_Database extends MySQL_Database
methods open, close query (which override MySQL Database)

I know this isn't exactly what you're saying - but I wanted to make it
more extreme to be more obvious.
It's ALL good - although every answer seems to beg another question!
In this case - abstract methods?
Is this another OOP thing that PHP4 doesn't do?

If you're basically creating a MySQL_Database class then overriding most
of the methods in the child class, you should look at whether your
design is appropriate or not.
Word.
Fortunately, I didn't fall into that trap.
In fact, in designing my project, I (wrongly) presumed that I could not
overrride functions in PHP.

That's not to say overriding is *never* appropriate - in many cases it
is. But as part of the overriding, you generally end up calling the
parent class method, also.
?!
So if the parent has "$parent->foo",
And the child overrides that with "$child->foo",
BOTH functions will fire when the child does?!
... but only sometimes?

Wassat about?!

Jul 23 '07 #38

P: n/a
Michael Fesser wrote:
.oO(Jerry Stuckle)
>Michael Fesser wrote:
>>It's been a long time since I worked with Java and C++, but it looks
like you're right in these cases. I came from the Pascal/Delphi world;
in Object Pascal you have to explicitly call inherited constructors and
destructors.
Object Pascal is not a true OO language. It's an OO extension to a
structured language (and not a real good implementation at that - there
are several holes in the way it is implemented). The ones I mentioned
are true OO languages.

Depends on how you define "true OO language". Many people don't even see
Java as a true OO language (mainly because of the scalar types IIRC).
And when comparing C++ and Delphi, I clearly prefer the latter, its
object model has some really nice and handy features (properties with
read-only or write-only access for example, I like that).

After all it all comes down to how strictly you want to follow a
paradigm. It doesn't really matter if we're talking about OOP or MVC for
example. Some people prefer to follow the rules as strictly as possible,
but for me that would cause more troubles than it would solve. Sometimes
you simply have to think more practical than theoretical.
>>It would. A::doSomething() just has to check if $this->data is empty and
react accordingly.
No, Micha, it is improper OO. The base class is depending on something
form the derived class.

I still don't see it this way. The derived class just performs a
different initialization of the data. The base class will still work
with or without that, because it already has this method ifself. It's
just overwritten by the child classes as necessary. I could even have
declared A::doSomething() as abstract, so child classes would be forced
to overwrite/implement it.
In a true OO system, the parent is initialized before the child. In
true OO languages such as Java and C++, this can be performed by passing
a parameter to the base class.

It's incorrect here because you 1) are not initializing the base class
first, and 2) are exposing the base class implementation.

Now what happens to the derived class(s) if you change the name of your
base class variable? Part of the OO design is the derived classes are
independent of the base class implementation.
It's not always possible to initialize an object just by passing all the
required data to the constructor, sometimes you have to perform
additional task in separate methods. That's not a problem. And calling a
child's method from a parent's method is not only allowed, but very
common and important (virtual methods, polymorphism, things like that).
It is ALWAYS possible to initialize the base object via constructor
parameters in a properly designed OO system.

But we're not talking about polymorphism here. That's an entirely
different subject.
> Additionally, in proper OO, A::data would be
private to the base class.

Sure, can be done. But I prefer to declare my properties as protected,
if they are supposed to be accessed in derived classes. I don't want to
write getters and setters for every single member variable. While it
would be "true OO", it's usually too much work for nothing. Things are a
bit different when properties should be accessible from the outside, but
even then I sometimes simply declare them as public.
Which is a classic example of overuse of "protected". Protected members
should be used rarely, if at all.
>And the constructor for A would be called
before the constructor to B ever got started.

Could be done easily in the modified version of my example.

Micha
I suggest you read up on OO from the experts. Booch, Rumbaugh and
Stroustrup are good starters.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #39

P: n/a
..oO(Jerry Stuckle)
>In a true OO system, the parent is initialized before the child. In
true OO languages such as Java and C++, this can be performed by passing
a parameter to the base class.

It's incorrect here because you 1) are not initializing the base class
first, and 2) are exposing the base class implementation.

Now what happens to the derived class(s) if you change the name of your
base class variable?
What if I change the name of a base class method? Same thing.
Part of the OO design is the derived classes are
independent of the base class implementation.
class A {
private $data;

protected function getData() ...
protected function setData($data) ...
}

class B extends A {
protected function initData() {
$this->setData('foo');
}
}

Where's the problem?
>It's not always possible to initialize an object just by passing all the
required data to the constructor, sometimes you have to perform
additional task in separate methods. That's not a problem. And calling a
child's method from a parent's method is not only allowed, but very
common and important (virtual methods, polymorphism, things like that).

It is ALWAYS possible to initialize the base object via constructor
parameters in a properly designed OO system.
Of course you can initialize it with constructor parameters to bring it
into a consistent and working state. But it might still be necessary to
call further methods to "fine-tune" its behaviour. You can't always pass
it all to the constructor, especially when there are things that are
entirely optional. You don't want to have a constructor with a hundred
arguments, taking into account every possible situation.

Additionally there might be cases, where the object A needs informations
or a connection to another object B, which is not yet available while
running A's constructor.
>But we're not talking about polymorphism here. That's an entirely
different subject.
It is, but also plays a role here.
>> Additionally, in proper OO, A::data would be
private to the base class.

Sure, can be done. But I prefer to declare my properties as protected,
if they are supposed to be accessed in derived classes. I don't want to
write getters and setters for every single member variable. While it
would be "true OO", it's usually too much work for nothing. Things are a
bit different when properties should be accessible from the outside, but
even then I sometimes simply declare them as public.

Which is a classic example of overuse of "protected". Protected members
should be used rarely, if at all.
Says who and why?

Micha
Jul 23 '07 #40

P: n/a
Sanders Kaufman wrote:
Jerry Stuckle wrote:
>Sanders Kaufman wrote:
>>Wow, now that I've done it that way, I can see why it's the better way.
By having to call the parent constructor from within the child
object, It gives the child better control.

For example, my parent has a "database" object, and a built-in
default way of talking to it; while the child has another way of
talking to it - each established in the constructor, and each running
a verification process to ensure it still works

Probably an incorrect implementation of OO, depending on exactly what
you're trying to do.

The purpose of OO is to allow the child object to use the parent
object's methods (functions) and to not have to write its own.

In the case of a Database object, the main purpose of the object is to
perform the communications. Another class which does it a different
way would be a different class.


I probably used the phrase "different way" poorly.

What I mean is that my database class, by default, connects to my
primary database server. But other classes in my architecture,
extending that one, may need to contact a different server.

So, by having the child modify the parent connection parameters, it can
talk to whoever it needs to... not just my primary.

There are two ways to look at this. The more portable way would be to
have a class which just connects to a database but doesn't actually
define the database. Then you could have a derived class
"DefaultDatabase" which connects to your default.

Another way would be to have the database name as the default parameter
to the constructor for the Database class.

Both are "correct" implementations. Which I would use would depend on
other factors. For instance, if the only thing different were the
database name, chances are I'd take the default parameter route (and not
even create other database classes - just pass the database name when I
create the object). However, if I'm going to have different functions
for the databases, chances are I'd go the route of having multiple
derived classes.
>
>Now that doesn't mean you shouldn't have a database object which
doesn't have children. For instance, as a simple example, you might
have:

class Database
member database name
abstract methods open (connect), close (disconnect), query

class MySQL_Database extends Database
methods open, close, query

class PostGres_Database extends Database
methods open, close query

But you should not have:

class MySQL_Database
member database name
methods open, close, query

class PostGres_Database extends MySQL_Database
methods open, close query (which override MySQL Database)

I know this isn't exactly what you're saying - but I wanted to make it
more extreme to be more obvious.

It's ALL good - although every answer seems to beg another question!
In this case - abstract methods?
Is this another OOP thing that PHP4 doesn't do?
Yes, abstract methods are a PHP 5 implementation (and in most other OO
languages). It means the base class has defined but not implemented the
method. This makes the base class an "abstract class", and you won't be
able to instantiate an object of that class.

Abstract classes are used for inheritance. A derived class must
implement all of the abstract methods in the base class (or it, too,
will be an abstract class). An abstract class with only abstract
methods would be an "interface", as Toby mentioned in another post.
>
>If you're basically creating a MySQL_Database class then overriding
most of the methods in the child class, you should look at whether
your design is appropriate or not.

Word.
Fortunately, I didn't fall into that trap.
In fact, in designing my project, I (wrongly) presumed that I could not
overrride functions in PHP.
You can override functions in PHP; it's very commonly done when the
derived class needs to do some work, also. But the derived class should
also be calling the function in the base class so the base class can
perform its work.
>
>That's not to say overriding is *never* appropriate - in many cases it
is. But as part of the overriding, you generally end up calling the
parent class method, also.

?!
So if the parent has "$parent->foo",
And the child overrides that with "$child->foo",
BOTH functions will fire when the child does?!
.. but only sometimes?

Wassat about?!
No, $child->foo() would have to call parent::foo().
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #41

P: n/a
Sanders Kaufman wrote:
Jerry Stuckle wrote:
>Sanders Kaufman wrote:
>>Vocabulary question: When I do this, what is the OOP thing that I'm
doing? You said that my use of an object as a property of the parent
class was "aggregation. So - when I use use "extends" to create the
child's reference to the parent - wassat? Marshalling? Inheritance?

Inheritance.

And then... overwriting functions would be polymorph?
And... PHP allows function overwriting?

Zat right?
Yes, and no. PHP doesn't have true polymorphism in the sense of other
OO languages, although what it has is effectively the same.

I say it doesn't have "true polymorphism" because PHP is an untyped
language. Typed languages such as C++ and Java differentiate between the
"apparent" type of the object (the type defined for the variable) and
the "true" type - that being what the object really is.

But since PHP variables are not typed, there is no "apparent" type - the
interpreter always knows the "true type".

So although the implementation is different - the effect is exactly the
same, and you can correctly consider it polymorphism.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #42

P: n/a
Sanders Kaufman wrote:
Interfaces - is that a PHP5 thing?
I don't think I've seen anything about it in 4.
Interfaces don't exist in PHP4. Nor do abstract classes IIRC.

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 32 days, 21:49.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 23 '07 #43

P: n/a
Sanders Kaufman wrote:
but what is it called when you use "extend" to create a child class?
See example 2.

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 32 days, 21:54.]

Parsing an HTML Table with PEAR's XML_HTTPSax3
http://tobyinkster.co.uk/blog/2007/0...table-parsing/
Jul 23 '07 #44

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>So, by having the child modify the parent connection parameters, it
can talk to whoever it needs to... not just my primary.

There are two ways to look at this. The more portable way would be to
have a class which just connects to a database but doesn't actually
define the database. Then you could have a derived class
"DefaultDatabase" which connects to your default.
Yeah, I started to go there - but that would have been one level of
complexity, too far for this architecture... or architect, anyway.
Better to just set a few properties and say "connect()".

Another way would be to have the database name as the default parameter
to the constructor for the Database class.
I'm not using parameters in my constructor.
I wasn't sure if I could have constructor parms at all when I started
this thing.

Also, the idea of doing this:
"$x = new MyObject($y, $z)"
instead of this:
"$x = new MyObject()"
just *feels* wrong to me.

I'm not sure why - but it's probably legacy cringing from some other
platform and package in my past.
>It's ALL good - although every answer seems to beg another question!
In this case - abstract methods?
Is this another OOP thing that PHP4 doesn't do?

Yes, abstract methods are a PHP 5 implementation (and in most other OO
languages). It means the base class has defined but not implemented the
method. This makes the base class an "abstract class", and you won't be
able to instantiate an object of that class.
Ooooh. That seems significant to my design - at least, for the next
iteration in PHP5, anyway.
My baseclass is not designed to be instantiated, and it kinda irked me
that it could be. I even added a bit of PHPDoc to warn the developer
not to try. But that's a lousy way to code!

Abstract classes are used for inheritance. A derived class must
implement all of the abstract methods in the base class (or it, too,
will be an abstract class). An abstract class with only abstract
methods would be an "interface", as Toby mentioned in another post.
Saturation level reached.
Information overload in effect.
Commence spinning of room.
Let's continue THAT part of the conversation in a few months, eh?

>Fortunately, I didn't fall into that trap.
In fact, in designing my project, I (wrongly) presumed that I could
not overrride functions in PHP.

You can override functions in PHP; it's very commonly done when the
derived class needs to do some work, also. But the derived class should
also be calling the function in the base class so the base class can
perform its work.
This looks like something I'm going to have to HEAVILY consider in the
next iteration of the code - abstract classes, interfaces and function
overrides.
Jul 23 '07 #45

P: n/a
Michael Fesser wrote:
.oO(Jerry Stuckle)
>In a true OO system, the parent is initialized before the child. In
true OO languages such as Java and C++, this can be performed by passing
a parameter to the base class.

It's incorrect here because you 1) are not initializing the base class
first, and 2) are exposing the base class implementation.

Now what happens to the derived class(s) if you change the name of your
base class variable?

What if I change the name of a base class method? Same thing.
You can't change the base class method - by definition, it's part of the
interface. But the variable is part of the implementation. In a proper
design you can change the variable (and, of course, the BODY of
functions which reference it) without changing the interface - and the
child classes.
> Part of the OO design is the derived classes are
independent of the base class implementation.

class A {
private $data;

protected function getData() ...
protected function setData($data) ...
}

class B extends A {
protected function initData() {
$this->setData('foo');
}
}

Where's the problem?
There's nothing wrong with this method.
>>It's not always possible to initialize an object just by passing all the
required data to the constructor, sometimes you have to perform
additional task in separate methods. That's not a problem. And calling a
child's method from a parent's method is not only allowed, but very
common and important (virtual methods, polymorphism, things like that).
It is ALWAYS possible to initialize the base object via constructor
parameters in a properly designed OO system.

Of course you can initialize it with constructor parameters to bring it
into a consistent and working state. But it might still be necessary to
call further methods to "fine-tune" its behaviour. You can't always pass
it all to the constructor, especially when there are things that are
entirely optional. You don't want to have a constructor with a hundred
arguments, taking into account every possible situation.
No, but then if you need a constructor with a hundred different optional
arguments, you should rethink your design.
Additionally there might be cases, where the object A needs informations
or a connection to another object B, which is not yet available while
running A's constructor.
Not in a proper OO implementation, there isn't.
>But we're not talking about polymorphism here. That's an entirely
different subject.

It is, but also plays a role here.
Not in the construction of the object.
>>> Additionally, in proper OO, A::data would be
private to the base class.
Sure, can be done. But I prefer to declare my properties as protected,
if they are supposed to be accessed in derived classes. I don't want to
write getters and setters for every single member variable. While it
would be "true OO", it's usually too much work for nothing. Things are a
bit different when properties should be accessible from the outside, but
even then I sometimes simply declare them as public.
Which is a classic example of overuse of "protected". Protected members
should be used rarely, if at all.

Says who and why?

Micha
Check out some of the "experts" in the field - like Booch, Rumbaugh and
Stroustrup.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #46

P: n/a
Toby A Inkster wrote:
Sanders Kaufman wrote:
>Interfaces - is that a PHP5 thing?
I don't think I've seen anything about it in 4.

Interfaces don't exist in PHP4. Nor do abstract classes IIRC.
Correct, Toby. Both are new to PHP5.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #47

P: n/a
Jerry Stuckle wrote:
You can't change the base class method - by definition, it's part of the
interface. But the variable is part of the implementation. In a proper
design you can change the variable (and, of course, the BODY of
functions which reference it) without changing the interface - and the
child classes.

Speaking of named methods and overrides...
I just now realized that I had a TableName property in both my baseclass
and my extended class... accidentally overriding, right?

But... can I still have it in both places, calling the baseclass
property with one of those :: operators?

Or does the overriding kill that altogether?
Jul 23 '07 #48

P: n/a
Sanders Kaufman wrote:
Jerry Stuckle wrote:
>Sanders Kaufman wrote:
>>So, by having the child modify the parent connection parameters, it
can talk to whoever it needs to... not just my primary.

There are two ways to look at this. The more portable way would be to
have a class which just connects to a database but doesn't actually
define the database. Then you could have a derived class
"DefaultDatabase" which connects to your default.

Yeah, I started to go there - but that would have been one level of
complexity, too far for this architecture... or architect, anyway.
Better to just set a few properties and say "connect()".

>Another way would be to have the database name as the default
parameter to the constructor for the Database class.

I'm not using parameters in my constructor.
I wasn't sure if I could have constructor parms at all when I started
this thing.

Also, the idea of doing this:
"$x = new MyObject($y, $z)"
instead of this:
"$x = new MyObject()"
just *feels* wrong to me.

I'm not sure why - but it's probably legacy cringing from some other
platform and package in my past.
Not at all. The whole purpose of the constructor is to initialize the
object. It is probably more common to pass parameters to the object's
constructor than not.

For instance, the constructor for the mysqli class:

mysqli mysqli_connect ( [string host [, string username [, string passwd
[, string dbname [, int port [, string socket]]]]]] )

If you pass a host, it will try to connect to the host. If you pass a
username, it will connect using that username. If password is
specified, it will also use that password, etc.

If no parameters are specified, then no connection is attempted.
>
>>It's ALL good - although every answer seems to beg another question!
In this case - abstract methods?
Is this another OOP thing that PHP4 doesn't do?

Yes, abstract methods are a PHP 5 implementation (and in most other OO
languages). It means the base class has defined but not implemented
the method. This makes the base class an "abstract class", and you
won't be able to instantiate an object of that class.

Ooooh. That seems significant to my design - at least, for the next
iteration in PHP5, anyway.
My baseclass is not designed to be instantiated, and it kinda irked me
that it could be. I even added a bit of PHPDoc to warn the developer
not to try. But that's a lousy way to code!
Yep, PHP5 will help in that way.
>
>Abstract classes are used for inheritance. A derived class must
implement all of the abstract methods in the base class (or it, too,
will be an abstract class). An abstract class with only abstract
methods would be an "interface", as Toby mentioned in another post.

Saturation level reached.
Information overload in effect.
Commence spinning of room.
Let's continue THAT part of the conversation in a few months, eh?
:-)
>
>>Fortunately, I didn't fall into that trap.
In fact, in designing my project, I (wrongly) presumed that I could
not overrride functions in PHP.

You can override functions in PHP; it's very commonly done when the
derived class needs to do some work, also. But the derived class
should also be calling the function in the base class so the base
class can perform its work.

This looks like something I'm going to have to HEAVILY consider in the
next iteration of the code - abstract classes, interfaces and function
overrides.
Yep.

I'd also recommend you pick up a decent book on OO in general. It will
explain things a lot better than we can here in the newsgroup.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jul 23 '07 #49

P: n/a
Jerry Stuckle wrote:
Sanders Kaufman wrote:
>Also, the idea of doing this:
"$x = new MyObject($y, $z)"
instead of this:
"$x = new MyObject()"
just *feels* wrong to me.

I'm not sure why - but it's probably legacy cringing from some other
platform and package in my past.

Not at all. The whole purpose of the constructor is to initialize the
object. It is probably more common to pass parameters to the object's
constructor than not.

For instance, the constructor for the mysqli class:

mysqli mysqli_connect ( [string host [, string username [, string passwd
[, string dbname [, int port [, string socket]]]]]] )

If you pass a host, it will try to connect to the host. If you pass a
username, it will connect using that username. If password is
specified, it will also use that password, etc.

If no parameters are specified, then no connection is attempted.
Yeah - I'm totally cool with the fact that some folks use parms in the
construction, and on a thinky level, I can certainly see where it would
be handy. But it really feels wrong.

I have the same issue with using voids... although I use 'em, it just
feels like the same kind of wrong.

>This looks like something I'm going to have to HEAVILY consider in the
next iteration of the code - abstract classes, interfaces and function
overrides.

Yep.

I'd also recommend you pick up a decent book on OO in general. It will
explain things a lot better than we can here in the newsgroup.
I'm not very good about learning from tutorial books. I get all the way
through, don't miss a thing, do all of the exercises... and then have no
idea what I learned.

If I'm gonna learn this stuff, it's gonna be because someone taught it
to me here and in the OOP groups. I'll probably also draw up a nice
poster to remind me about Inheritance, Polymorphism, Abstraction and
Encapsulation.
Jul 24 '07 #50

61 Replies

This discussion thread is closed

Replies have been disabled for this discussion.