The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Hybrid View

Design of higher-level classes

I was reading some of Vincent (voostind)'s earlier posts on this forum, particularly this one. I thought I had an OK handle on OOD before, but that post in particular and his talk about putting different objects together to produce certain functionality makes such wonderful sense. I love it. However, all the OOD discussions I've looked through were focused on interaction of relatively low-level classes - iterators, database classes, et cetera. What I'm still quite confused about is how to handle the development of higher-level classes. I mean, at some point, classes have to start being more specific to the website or application that one is creating, right? I think an example would probably be most effective, although I'd be really interested in anyone's opinions on or experiences with this.

I'm guessing you're looking for some real life examples of how to put "different objects together to produce certain functionality"

In one of my sites, I needed to make a search, when given a string, it searches different sections of the site, each section has a slightly different way of searching. eg a People section will be done by firstname/lastname, while an article section will be done by full text.

Thanks again mr tinkles. And Robo, it was helpful to see the same principles work at a higher level.

I guess what I really mean is that in OOP, you try to make every class as generic as possible (solve a general problem rather than your specific situation), but at higher levels in the application, that's not possible (the class has to have functionality specific to your application... right?). I just find this a bit confusing, so I wanted to see an example of a high-level class.

Good points, but then, that's the trouble with many OOP tutorials: they focus on these real-word metaphors and don't show you how they apply to programming. It would be nice to see an actual class that could be part of an actual website or PHP application...

Note that it says functionsnot class methods which can be over ridden in sub classes.

As far as over loading class methods is concerned, this is not something you need to do in PHP, as a loosely typed language, compared to Java for example - you throw more arguments than was defined at a class method and catch them with func_get_args() and examine the type with gettype(). What's more, PHP has an extension called the overload extension which effectively allows it to be more powerful that Java in this area - I wrote an article about it here. Although experimental today, this is becoming one of the key elements of PHP5 and will give PHP a unique advantage, as an extremely flexible language.

Yes, some of the classes that you build won't be generic enough and will only be specific to your website. Unfortunately, you can't have it all even with the power of OO programming. As long as you don't have too much website specific code, then it's okay since it's almost impossible to generalize everything such that it can be reusable anywhere and everywhere.

One of the rules of XP (extreme) programming is to just get the website working first. If you have to create code that will only work with that specific website configuration, then so be it. However, XP also recommends that later on in other iterations, that you can refactor your classes. So once you've got it working, you can then later on go back, if you wish, and make your class hiearchies, etc. less coupled and more refined.

It's a waste of time in my opinion to try and always to create something so generic everytime unless you've got a lot of time to kill. However, that doesn't mean you shouldn't strive to create generic classes the first time either. Just remember there's disadvantages to either extreme, and that it's usually better to walk the middle ground. Additionally, another case for NOT choosing to create generic classes is that in general sometimes making something as generic as possible results in slower code, so depending on your situation, that may play a large factor in your designs.

PHP has all of these. It is perfectly possible to adhere completely to OOP principles, even in version 4.

So does peanut butter and jelly. It is possible to adhere to OO principles with stuctured programming langs, such as BASiC and C, and FORTRAN. Doesn't make those langs OO...

While PHP doesn't have overloading (which doesn't really have to do with inheritance anyway)

inheritance can have a profound affect on overloading, so it's relevant. overloading/riding inheritance dependent.

I don't know what you mean by one level of inheritance... maybe that dual inheritance isn't possible?

No dual inheritance please, though possibly OO, more problems than worth. How come, now, you the expert?

Do you even understand what overloading and overriding is, and more importantly what the difference is? I think that if you would, you wouldn't have made that statement because it has nothing to do with object oriented programming.

I understand overloading/riding better than you, as neither exists without OO. The above quote will prove you wrong...

What's more, PHP has an extension called the overload extension which effectively allows it to be more powerful that Java in this area - I wrote an article about it here. Although experimental today, this is becoming one of the key elements of PHP5 and will give PHP a unique advantage, as an extremely flexible language.

The use of 'magic' functions to enable OO functionality (experimetal or not) proves my contention that PHP not OO compliant/capable! java does it WITHOUT overload/override KEYWORDs, hello. write that in your article, seems relevant...

Kind of like this:

I have a peanut butter and jelly sandwich.
I call 'magic' function to change to pastrami and swiss cheese with that good mustard. ummm tasty.

Well ignoring your not-so-hidden agenda to show PHP coders up for the charlatans they are for a moment and taking this at face value.

So does peanut butter and jelly. It is possible to adhere to OO principles with stuctured programming langs, such as BASiC and C, and FORTRAN. Doesn't make those langs OO...

And writing in C# or Java doesn't necessarily make you code great OO. How many people place all their code inside main()...

The use of 'magic' functions to enable OO functionality (experimetal or not) proves my contention that PHP not OO compliant/capable! java does it WITHOUT overload/override KEYWORDs, hello. write that in your article, seems relevant...

It think you'll find if you re read the article carefully, you'll find PHP is doing something which Java (and other strongly typed languages) don't have and cannot have.

With a loosely typed language signatures are less important that they are with strongly typed - you'd do effectively the same with Python for example. If you're arguing the loosely typed languages are fundamentally not object oriented you'll have to take that all the PHP, Perl, Ruby and Python programmers who are quite happily writing OOP code, blissfully ignorant of the fact that is just isn't.

What PHP's overload extension does is something unique, that you cannot do with Java or any other stronly typed language (without some major workarounds). But hey - prove me wrong if you can;

I can now call anything via someclass. While you dismiss this you fail to see it's value in things such as web services and otherwise, where PHP interacts with other systems. This is not overloading in the sense of Java or other strongly typed languages. This is something unique to loosely typed languages.

In my opinion, strongly typed languages are stuggling to keep up with loosely typed languages. One whole issue that is only occassionally discussed in todays web services hype is how XML schema was used to give strongly typed languages a change. An interesting footnote is MIME rpc: http://www.mime-rpc.com/ - the whole web services "thing" could have been a whole load easier - MIME rpc is perfect for loosely typed languages. As it is the only way to develop at an acceptable speed these days with a strongly typed language is to take a language like C# and super charge with tools (which suits the tool vendor very nicely).

Where I agree with you, in something you haven't actually said yet, is that today, with PHP 4, the programming "experience" is not all it should be. It needs to standardise things which currently every PHP developer has their own solution for, such as exception handling, static members, abstract classes and so on. That's exactly why the lead PHP developers are entirely focused on PHP 5 right now. You should read more at http://www.phpvolcano.com/eide/php5.php?page=front for a nice intro.

Inheritance, sort of. One level only. More like 'include' or 'interface', barely inheritance.

now if even a OOP shovel like me knows you are talking out of your nether regions there I suggest you get to grips with PHP OOP before regurgitating shovel-bait about what it can and can not do.

TheDarkEye , I am not quite with you but I thought that Harry's code showed now $n variable arguments were handled? - if not just take a look at the function handling functions at php.net especially variable functions and create_function() which is immensly useful , especially in callbacks in php-gtk where I can create functions based on user input.

I dont think it gets much more OOP than a GUI , but as I say I am an OOP shovel In fact the only thing that really hurts me in my day to day meanderings is lack of decent dereferencing which is happily now being rectified (and lack of a basic OOP grounding which means I keep reinventing the wheel ..& at a penalty of course )

Well ignoring your not-so-hidden agenda to show PHP coders up for the charlatans they are for a moment and taking this at face value.

Guess I deserve that. If any agenda is hidden, it's to perhaps understand better/more how PHP does OO, make all better coders.

And writing in C# or Java doesn't necessarily make you code great OO. How many people place all their code inside main()...

OR worse, write horrible OO, because they can, or don't know any better...

It think you'll find if you re read the article carefully, you'll find PHP is doing something which Java (and other strongly typed languages) don't have and cannot have.

I read and understood the article. I'm fairly sure I got it, though correct me wrong.

I can now call anything via someclass. While you dismiss this you fail to see it's value in things such as web services and otherwise, where PHP interacts with other systems. This is not overloading in the sense of Java or other strongly typed languages. This is something unique to loosely typed languages.

I quess this is where you and I disagree. It's kind of overloaded, as in:

$point->draw(5,9);
$point->draw();

You can overload on number of args, could be useful, could be dangerous. What results do you get with:

Now, I know PHP no do this (or please show me), thats OK, just don't claim it does.

Your example of overloading can be easily accomplished in Powerbuilder (been awhile) by use of the ANY variable type and still supports datatyping. Would seem reasonable to me that you could do the same in Java, though I haven't tried.

PB:

return functionname(any, any, any, any, any...N)

You have now overloaded functionname for up to N args, just call:

functionname(int, string, long) OR
functioname (string)

you of course still need to code for all the combo of args you want to use, much like you example, but with datatyping (or NOT)

That is god awful code, OO, or otherwise, just for example purposes...

Seems PHP kinda loses "this" references to me, when inheriting more than 1 level. Of course if only inherit one level, not an issue. You can try this by instantiating a b object, but the $this->a(); creates infinite loop! But not with 2 levels. Seems I have a grip, what about you?

parent::b .... which is doing exactly what you tell it to do ? what else would you expect to happen ?

if you write code that is deliberately flawed then what else can it produce ? , if we are daft enough to put $this->a() in the base class a constructor then we have to be sure that it is overridden less we expect the results above.

if you write code that is deliberately flawed then what else can it produce ? , if we are daft enough to put $this->a() in the base class a constructor then we have to be sure that it is overridden less we expect the results above.

its flawed (from my perspective) in that you basically say
$temp=2;//then call b() so
$temp=1;
echo $temp;
//why does temp not ==2 ?

at least thats what your code does and returns exacly what it has been created to do.

If your argument is that its easy to write bad code with PHP especially OOP then no-one will argue, but you are saying that PHP OOP is not capable as is and thats simply not true.

That PHP has until now required workarounds to create some OOP features , private variables, abstract classes etc too is accepted, again that does not limit your possibilities, in the same way as PHP not having application scope globals & variables does not stop one from easily achieving such.

Here, a Ferrari object is passed to a method that accepts a Car object. But that's not overloading, because a Ferrari IS a Car. The method 'drive' expects a Car object, and gets a Car object. No overloading involved whatsoever. Polymorphism yes. Overloading no.

This doesn't work, because there is no 'string' type in Java, and the 'int' type is not of type Object. If he would have written:

Code:

method (String, Integer, ...N);

Then it would have worked, because both class String and class Integer are subclasses of class Object. Again, this is not overloading, but polymorphism. Anyway, what would be the use of doing this? The method 'method' accepts a number of Object instances, so it can only call methods defined in that particular class, and not any method defined somewhere else (it's Java, remember!). This is where PHP differs. Because in PHP you can do this:

PHP Code:

function method($object) {$object->drive();}

The method 'method' above calls the method 'drive' on an object '$object'. Why is that so special? Because nowhere is it defined that the variable '$object', or the class it is an instance of, must support the method 'drive'. Also, if two objects happen to support the method drive(), that doesn't mean they have to be related in any way through inheritance. That's something you can only try to approach with Java using interfaces, but it's nowhere near as flexible as PHP. Or Ruby. Or Python. Or any other object oriented language with dynamic late binding... (Smalltalk anyone?)

"That is god awful code, OO, or otherwise, just for example purposes..."

The example being, poor self reference, and poor variable shadowing. Would a better example, that shows the same behavior be any better? The code a silly as it is, is actually very possible in the real world when one wants to extend existing objects that require class constructors???

its flawed (from my perspective) in that you basically say...

$temp exists in both b and c. If I am a c object, and I set my $temp=2, then:

echo $temp;

should output 2 regardless of what any ancestors do. If $temp is a class level variable, then $temp should exist in both the c and b object as their own class vars. If $temp class var across inheritance, then overriding big problem...

Overloading has NOTHING to do with OOP. Overriding does, but overloading doesn't.

This doesn't work, because there is no 'string' type in Java, and the 'int' type is not of type Object. If he would have written:...

you are correct, but was it so hard to get the idea, as in you know what I meant, or maybe not?

Here, a Ferrari object is passed to a method that accepts a Car object. But that's not overloading, because a Ferrari IS a Car. The method 'drive' expects a Car object, and gets a Car object. No overloading involved whatsoever. Polymorphism yes. Overloading no.

See the above definition of polymorphism, means having "having multiple forms", NOT multiple names. The example has little or nothing to do with polymorphism.

As defined, may not work reliably. True, all Ferrari's are Car's, but not all Car's are Ferrari's. If drive() method written for Car, and doesn't take potential for Ferrari object, then implicit cast will occur and you will lose Ferrari functionality in drive() method and get just Car (will need to cast back to Ferrari object).

If you want a Ferrari and want to drive, but get yugo, would you be happy?

Not a good OO example. Ferrari different than Car, though is car. Do you take your Ferrari to a Car mechanic?

Lastly:

The method 'method' above calls the method 'drive' on an object '$object'. Why is that so special? Because nowhere is it defined that the variable '$object', or the class it is an instance of, must support the method 'drive'.

That's a good thing? And when an object that doesn't have drive() is passed, what now?

Of course polymorphism has everything to do with OOP. I never said otherwise. It was you who said that overloading had everything to do wich OOP, which is incorrect. You mix up the various definitions of polymorphism in the link you posted (overloading is a kind of polymorphism according to that definition, but that kind of polymorphism had nothing to do with OOP), and I only pointed that out.

Originally Posted by mr tinkles

What do you think OOP means?

You're asking me? Want my resume? And while we're at it, may I see yours?

The person who tells others that they don't know enough about some subject, is surprisingly often the one who knows the least about that subject...

Originally Posted by mr tinkles

See the above definition of polymorphism, means having "having multiple forms", NOT multiple names. The example has little or nothing to do with polymorphism.

The example has everything to do with polymorphism. A Ferrari (in my example) is another 'form' of a car; not another name.

Originally Posted by mr tinkles

As defined, may not work reliably. True, all Ferrari's are Car's, but not all Car's are Ferrari's. If drive() method written for Car, and doesn't take potential for Ferrari object, then implicit cast will occur and you will lose Ferrari functionality in drive() method and get just Car (will need to cast back to Ferrari object).

Correct. And this is precisely the problem with your so-called overloading example 'method (Object o1, Object o2, ...N)'. Again, I only pointed that out using this example. The only one you're arguing with here is yourself.

Originally Posted by mr tinkles

Not a good OO example. Ferrari different than Car, though is car. Do you take your Ferrari to a Car mechanic?

Why not? A ferrari is a 'form' of a car (in your speak), so it supports everything a normal car does. So if it doesn't work because of a simple 'car' problem, any Car mechanic can fix it. That's the whole point of polymorphism. The Ferrari -> Car (Or Student -> Person) example is a famous (or infamous) one. And now you're saying it's a bad example? That's a good one!

Originally Posted by mr tinkles

That's a good thing? And when an object that doesn't have drive() is passed, what now? I can call unknown methods on unknown objects, how it that good?

It's not good OR bad. It's different. It allows you to do either very stupid things, or very great things, depending on your knowledge and experience. And it's totally different from Java (or C++).