share
Stack OverflowWhy is OOP hard for me?
[+244] [19] netrox
[2010-01-09 23:53:13]
[ php oop class concepts ]
[ http://stackoverflow.com/questions/2035449/why-is-oop-hard-for-me ] [DELETED]

I have trouble writing OOP in PHP... I understand the concept but I never create classes for my projects... mainly because it's often a small project and nothing complex. But when I read OOP, it seems more difficult to code than writing simple procedural statements. It also seems to take a lot of room as well with so many empty abstract classes and that can be easily lost in the land of objects... it's becoming like a junkyard to me.

Also, I noticed that virtually all instructions on how to use OOP use "car" or "cat" or "dog" analogies. Hello... we're not dealing with animals or cars... we're dealing with windows or consoles. You can talk about analogies to death and I will never learn. What I want is see a code that's written to show how objects are created - not, "aCow->moo!"

For example, I want to see a browser window object displaying say... three inputs. I want to see an "object" created to output a window with three inputs then I want to see how overriding works, like change the window object to display only two inputs instead of three inputs. I think that would make learning more easy, wouldn't it? Any recommended tutorials of that nature instead of quacks, moos, and woofs.

(104) Up-voted because of the animal analogies...they irritate me, too. =) - David Thomas
(17) glad I am not alone! My Java instructor kept telling me about "cars" and "radios" and how controls of radio are "interfaces" ... and never showed code! I withdrew the class. - netrox
(4) Expanded my answer to cover interfaces. (Mine is the long one!) - Chacha102
(2) hahah, I remember when I thought this too years ago, I too was a PHP developer, and I just couldn't understand if/why/when I should write my code as OOP.... it wasn't until I transitioned to ASP.NET that I started programming OOP... AND yes I HATE the Car, bear, dog examples, they are great for explaining, but the books never seem to show you a REAL OOP example! - Dal
(3) Expanded my answer to cover Barking Cats. Because I'd hate a world, where cats can bark. - Chacha102
Guilty. Teaching java I used the VCR-analogy. Cause everybody knows it was Panasonic who made all the VCRs, all the other brands just put their own cool fronts on it, hence interface. - Martin
"they are great for explaining". That's why books and teachers use them. Go look at the multitude of sourcecode of open source projects if you want to see some real code examples. - darren
I would recommend learning OOP in for example C# or Java instead of PHP. And to learn it in some regular applications (Console at first probably) and not web stuff. - Svish
Personally I found Objects First with Java and BlueJ very useful when I first learned OOP -- bluej.org :) - Svish
Hey @netrox, anyway you could accept my answers? It would be really cool to get the Guru Badge. - Chacha102
Thanks a bunch! - Chacha102
(2) (cat && dog)? CAT RUN! - denica
"I never create classes for my projects... mainly because it's often a small project" At risk of sounding like a heretic, OOP is not appropriate, necessary, or helpful for every project. There is truth in this old joke: ariel.com.au/jokes/The_Evolution_of_a_Programmer.html - mickeyf
Your question shows that you don't want to be a software engineer, but you always want to be a coder, programmer or developer. That's the difference as I can see between the example of cats & dogs and examples of windows & consoles. That is what I think! - Arfeen
OOP literature fills up with those stupid examples because explaining how objects work is easy, but thinking with them is hard. However, at the same time, it's easy -- so easy that you don't even think of it, and go straight for the procedural way that requires you to think in more abstract terms. If you're a PHP person, I recommend working with the Zend library for a while. There's no need to use the whole MVC framework if you don't want to; just try working with forms or even just input filters. It's not totally perfect but it's helped me begin to genuinely understand OOP. - LinusR
(1) If you're having issues learning something, it's not someone else's responsibility to teach it to you. The analogies are being used to try to help. Try being a little more grateful o_O - Cory Collier
[+216] [2010-01-10 00:03:00] Chacha102 [ACCEPTED]

Here are a few examples of classes that I find to be in the genre of OOP. Enjoy!


Form Class Example

Start with a Base Form Class that can output <input> fields. Very simple, has an array to hold the fields that are going to be outputted, have a method for adding fields, and has a function that will display the form to the page.

class Form
{
    protected $inputs = array();
    public function makeInput($type, $name)
    {
         echo '<input type="'.$type.'" name="'.$name.'">';
    }

    public function addInput($type, $name)
    {
         $this->inputs[] = array("type" => $type,
                "name" => $name);
    }

    public function run()
   {
       foreach($this->inputs as $array)
       { 
          $this->makeInput($array['type'], $array['name']);
       }
    }
}

$form = new form();

$form->addInput("text", "username");
$form->addInput("text", "password");

$form->run();

Then, lets say we wanted to create a class that can deal with the special style of <textarea> inputs. Well, we override the run function to filter out any input that have the type textarea, and redirect them to another function that we create that can deal with <textarea>s

class textAreaForm extends Form{

   public function run()
   {
        foreach($this->inputs as $array)
        { 
           if($array['type'] == "textarea")
           {
               $this->makeTextArea($array['name']);
           }
           else
           {
               $this->makeInput($array['type'], $array['name'];
           }
        }
    }

    public function makeTextArea($name)
    {
          echo '<textarea name="'.$name.'"></textarea>';
    }
}

$textareaForm = new textAreaForm();

$this->addInput("text", "username");
$this->addInput("text", "password");
$this->addInput("textarea", "comment");

What we have done is taken a base class that holds enough functionality to be usable, and then created another class that derives from it to add additional functionality.

Some may argue that in this specific example, the second class should just be added to the first class, because all forms should be able to process <textarea>s , but it is a start place.

Another example might be a database. You build a base database class that has all of the functions that would be required to access a Database, but then you can create a class derived from it to specialize in Postgres Databases.

Database Example

First create a database class that lays out the functions that would be needed to interact with a database. It doesn't do anything yet, but it ensures that whoever is going to write a specialized class knows the functions they need

class Database
{
    public function connect($host, $user, $pass, $database)
    {        
        // This function doesn't do anything normally
    }

    public function query($query)
    {
        // again, nothing
    }

    public function select_db($database)
    {
        // FOR THE LAST TIME! NOTHING!
    }
}

You could even make all of the functions abstract so if someone doesn't implement them, they get a PHP error

abstract class Database
{
    public abstract function connect($host, $user, $pass, $database)

    public abstract function query($query)

    public abstract function select_db($database)
}

And then add functionality to it based on the type of database we are using.

class MySQL extends Database
{
    public function connect($host, $user, $pass, $database)
    {        
        mysql_connect($host, $user, $pass);
        $this->select_db($database);
    }

    public function query($query)
    {
        return mysql_query($query);
    }

    public function select_db($database)
    {
        mysql_select_db($database);
    }    
}

and Finally

Data Class Example

This one I came upon recently. Lets say that I wanted to create an object that just contained a bunch of data. Well, I can very easily do that by using a new instance of stdClass. But, lets say that I wanted to make the class from an array. We can specialize stdClass and make it easier to work with:

class stdDataClass {

/**
 * Constructs the Object
 *
 * @param array|object $fields An array or object of data to be assigned as
 * class members on initalization of the class
 */
public function __construct($fields = array())
{
    // Check if the passed in variable is an object
    if(is_object($fields))
    {
        // Grab the accessible variables and use them as the fields
        $fields = get_object_vars($fields);
    }

    // Check if any fields were passed in, if they were, assign them to members
    if(count($fields) > 0)
    {
        foreach($fields as $key => $value)
        {
            $this->$key = $value;
        }
    }
}

// .. more stuff ...

}

This makes a array you pass in like this

$obj = new stdDataClass(array("test" => "foo"));

Be accessible like this

echo $obj->test; // echos 'foo'

Just a note, I never extends stdClass as stdClass has no methods or properties, and is basically an empty class.

Interfaces

Basically, anything that can be accessed from outside of a class is considered an 'interface'. It means that these are the function and variables that another class can interact with freely.

AKA, in this class, there is only 1 function get in the interface:

class Mine{

    public function get($key);
    private function doSecretStuff();

}

If you want to make 'sure' that there are certain interfaces in a class, you create an interface

interface Mine{

    public function get($key);

}

This assures that any class that implements Mine will have the functions in its interface

class Yours implements Mine
{
    public function get($key);
}

The following class for example will result in the PHP script giving an error and stop running:

class Yours implements Mine
{

    public function noGetHere($key);
}

The importance of an interface is simple, as it ensures that you are able to call a function. In this case, this function will NEVER get a 'method undefined' error.

function test(Mine $class)
{
   echo $class->get("Hello");
}

Because of the use of Type Hinting (making sure that $class either is an instance of Mine, extends Mine or implements Mine), $class can never not have the method $class->get();. I dare you to make an example in which this exact function, combined with the above interface, results in a method not found error.

Final Keyword

The final keyword is a method to make sure that something can't be changed. Just because the OP argued that in OOP, you can make a cat say 'bark', I feel like discussing this. It also furthers the example of why I have no life. :)

Basically, if you create a cat

class Cat
{
    public function speak()
    {
        echo "Meow";
    }   
}

You can write over the speak function like so

class BarkingCat extends Cat
{
     public function speak()
     {
         echo "Bark";
     }
 }

But, if you use the keyword final to make the method immutable, the above class will have an error, saying that you cannot overwrite functions that have declared the final keyword.

class Cat
{
    final public function speak()
    {
        echo "Meow";
    }   
}

There we go, no more barking cats. select_db($database); }

    public function query($query)
    {
        return mysql_query($query);
    }

    public function select_db($database)
    {
        mysql_select_db($database);
    }    
}

and Finally

Data Class Example

This one I came upon recently. Lets say that I wanted to create an object that just contained a bunch of data. Well, I can very easily do that by using a new instance of stdClass. But, lets say that I wanted to make the class from an array. We can specialize stdClass and make it easier to work with:

class stdDataClass {

/**
 * Constructs the Object
 *
 * @param array|object $fields An array or object of data to be assigned as
 * class members on initalization of the class
 */
public function __construct($fields = array())
{
    // Check if the passed in variable is an object
    if(is_object($fields))
    {
        // Grab the accessible variables and use them as the fields
        $fields = get_object_vars($fields);
    }

    // Check if any fields were passed in, if they were, assign them to members
    if(count($fields) 

(1) that's a good one... I like it. :) - netrox
I think it is taking so long for people to upvote it because it is so long... lol. - Chacha102
(8) Up-voted for the awesomeness, and for being the best explanation I've come across so far for real-world use of OOP. Though admittedly I'm only as hobbyist, and haven't invested as much time/effort as professionals in the field, so my ignorance is almost certainly my fault... =) - David Thomas
(2) Good answer - shame it's a community post! - adam
(13) @ricebowl I'm a 16 year old who doesn't get paid to do this. I just have no life. lol. Its actually been a good 2-3 months since I did a post this large. - Chacha102
(10) @Chacha102, you're 16? Damn, you're doing well and I am 37! I hope you'll write a book on OOP for people like me! I'd definitely buy it! :) - netrox
I am actually starting to write a programming column at layeredbyte.com. I'm not exactly aiming at OOP programming though. Just simple web design stuff. - Chacha102
@Chacha, thanks for making me feel useless... =p I'd suggest perhaps taking this into a blog, I'm coming back to this answer (up-voted, made-favourite and bookmarked in FF) every time I feel like trying OOP again. - David Thomas
@ricebowl anytime! :) - Chacha102
(1) I wish I could upvote this more than once. - Rahul
I have a question, in your example you defined a class and an interface for "Mine", can you actually have a class and an interface with the same name in PHP? Also is it common to start interfaces in PHP with an I like IMine? I am not trying to correct you, I am seriously asking because I am familiar with OOP but not in PHP. Thanks! - John Isaacks
@John You can only use a class name as a class or an interface. Not both, unless you use namespaces. - Chacha102
(1) not sure why, but i never considered having a form class. thats brilliant! - jordanstephens
poor barking cat :( Thanks for this amazing tutorial :) - Nort
this is f'n awesome! - luckytaxi
Truly amazing, thanks. - GG.
1
[+21] [2010-01-10 00:00:53] adam

The reason animals, cars etc are used is that the easiest way of understanding OOP is to use real-world objects:

  • A car is an object
  • A car has 4 wheels (property)
  • A car can beep (method)
  • My car is an instance of car
  • A 'Robin Reliant' is a type of car with only three wheels (extending)

So you'll be needing an object of 'window', with a method to create an input. Although cats would be a better analogy...


(11) we're surrounded by objects... we don't see objects magically transform into something else like objects in OOP do. That's why I don't like those analogies. Do you see a dog magically change his bark to moo? Do you see a cat start to woof? That's not the way real life objects are but with OOP, it's possible. - netrox
(9) You've misunderstood. A specific dog is an instance of class 'dog'. A cow is not a subtype of dog, so no - a dog would not start mooing. When you create an instance of a class, properties are essentially fixed at that point. So you could say dogs are medium sized, terriers (an extension of 'dog') are small. If you create an instance of dog, it would be medium sized. If you create an instance of terrier, it would be small. Neither would moo, ever. - adam
@netrox, are you familiar with the concept of common descent in animals? - jball
jball, yes i understand the concept of common descent. adam, I understand that when you create a class, it's a "blueprint" but do you really see "blueprints?" I see a beautiful house but I don't see a blueprint for the house even though it's built using a blueprint. But then even with extended objects, you can change the cat to say bark instead of meow. Doesn't seem right but it's possible. - netrox
(2) Don't think blueprint, think common features. - adam
car can hardly beep, but it can honk indeed. - dusoft
I agree with Adam. I think its a matter of perspective. A class object isn't a blueprint (an Interface is though). - rally25rs
There are ways to make sure that the Cat only can say 'Meow', just btw. Its called the final keyword. - Chacha102
(2) And there we go, I have covered how to make cats not bark. :) - Chacha102
(4) @netrox, Using OOP you can extend House and add a method called FlyToTheMoon(). You can extend Cat and override the Meow() to return -1. OOP only provides the construct to create reusable code, it's up to YOU and your team to make sure your code makes sense. - Kevin
(2) @Kevin: Thank you. These cat/dog examples are as logical as in "real-world" programming examples. You can make real-world stuff retarded too if you really wanted to. - Mark
Beep shouldn't be an event? - Ramiz Uddin
@Ramiz if you're being beeped at, it's an event - you need to listen for it and action it. Beeping your own car is a method. - adam
2
[+18] [2010-01-10 01:05:58] Robert Cartaino

Forget the quacks, moos, and woofs.

To really get object-oriented programming, you have to get past those "a dog is-a mammal" metaphors. They don't translate into most types of applications. Object-Oriented programming is so much more effective when you think in terms of roles, responsibilities, and behaviors.

I would really recommend this book to help you out:

Object Design: Roles, Responsibilities, and Collaboration [1]

alt text

It was the first book I read where I finally "got it."

[1] http://rads.stackoverflow.com/amzn/click/0201379430

3
[+9] [2010-09-11 02:53:36] MBCook

There are some good examples here. The top voted answer (which was accepted) does a great job of explaining the basics, and is certainly better than many of the FlyingCar extends Car implements Flying and Car extends Vehicle and Vehicle extends ManufacturedGood examples you might get in school or textbooks.

When I first learned OOP after coming from C, it didn't really click for me either. I used classes as like C structs: just a way to lump variables together. I also had accessor methods, because you're supposed to, all books shoed them. At first, they just seemed like extra typing instead of using public properties.

As time went on I started adding other methods to my classes, and objects become "whole" instead of special structs. Bundling the code together makes maintenance and trying to understand the code easier. It cleans up your code quite a bit to be able to write

myThing.doBehavior(1, 3, false);
someThingSubclass.doBehavior(2, 7, true);

instead of

do_behavior_for_thing(&myThing, 1, 3, false);
do_behavior_for_thing_subclass(&someOtherThing, 2, 7, true);

After a while and you internalize that, you'll use objects and become comfortable. Then one day you'll use inheritance (which is the real secret power) and see just how much easier your life becomes (if done correctly). Compare putting the top and bottom code above into a loop:

Thing theThings[] = {myThing, someThingSubclass, aThirdKindOfthing};
for (int i = 0; i < theThings.length; i++)
    theThings[i].doBehavior(7, 3 * i, true);

vs.

Thing theThings[] = {myThing, someThingSubclass, aThirdKindOfthing};
for (int i = 0; i < theThings.length; i++)
   if (theThings[i].kind == 1)
       do_behavior_for_thing(&theThings[i], 7, 3 * i, true);
   else if (theThings[i].kind == 2)
       de_behavior_for_thing_subclass(&theThing[i], 7, 3 * i, true);
   ....

The top loop is two lines. I can keep adding subclasses of Thing to my array and it works fine. In the bottom loop, every time I need to handle a new kind of object, I need to edit the if statements.

Game example

It makes it easy to make small changes to existing objects. Let's take a game, something like Robotron or Geometry Wars where enemies might chase the player. Think of an enemy who blindly chases the user's current position, we'll call him Zombie.

What if you want to add a second, harder enemy, called SmartZombie? You could just copy the Zombie class and edit it, but that would leave you with a bunch of duplicate code. But why not change the Zombie class from something like this:

public class Zombie {
    public NextMove makeNextMove(GameState game) {
        TargetPos pos = game.getCurrentUserPosition();
        // process from there
    }
}

to

public class Zombie {
    protected TargetPos getTargetPos(GameState game) {
        return game.getCurrentUserPosition();
    }
    public NextMove makeNextMove(GameState game) {
        TargetPos pos = getTargetPos(game);
        // process from there
    }
}

With that little change, you can make your new Zombie chase the user's predicted position by overriding one little method:

public class SmartZombie extends Zombie {
    protected TargetPos getTargetPos(GameState game) {
        // Calculate where the user will be by the time we could catch him
    } 
}

Now, when the game asks the Zombie class for his next move, he will walk to where the user is. But if the game is given a SmartZombie instead, without having to know that something different needs to happen, the SmartZombie's makeNextMove function will be called (inherited from the Zombie class). makeNextMove will call the SmartZombie's getTargetPos (since we overrode the Zombie's method) and instead go towards the user's predicted position.

You can use this to easily make other zombies. You could make one that goes towards a random place, one that follows other zombies, all sorts of things. Each of these is a simple change with the above model, letting you have only one copy of the makeNextMove function (which could be really long and involved because it uses A* pathfinding, terrain detection, random staggering, trap avoidance, and other fancy things).

You don't even need to setup the getTargetPos when you first write the class. If you don't know you'll need to access it later, you don't need to make a method for it. When the time comes that you do need to make it easy to change some piece of functionality, that's when you can edit the Zombie class to put the part you need to be able to change into a small function you can easily override.

In my daily work

The system I spend my time on has to interface with many external systems. The basic operations are the same, but the way we communicate can be wildly different (XML, HTTP, other). Even individual implementations can be very different (between two XML interfaces).

But we have a class somewhat like this:

public abstract class abstactSystemInterfacer {
    public ReturnValue contactOtherSystem(InputData data);
    public boolean interpretResponse(ReturnValue value);
    public Status checkWithOtherSystem(Thingy thing);
    protected void helpfulMethodForSubclasses(....);
}

The code in the heart of the program is given a subclass and just calls contactOtherSystem and other methods it needs. It doesn't need to know if we're using XML to talk to the other system. It doesn't know at all.

So we can add new code without having to change the main loop. It doesn't need to have a new block of an if or switch statement added when someone new appears. If we have to work with someone new tomorrow who uses some method we've never used before (such as putting weird files in special FTP directories), we can do it without having planned for it before.

This kind of thing makes your life very easy, and the core code very clean. It's up to the subclasses to handle all the details. If you are making a game, you can make enemies this way. Each one implements their behavior in a function, and the game engine calls it. When you make a new kind of enemy, it's as simple as making a new class and instantiating it.

Over time, as you get tons and tons of classes, things can get a little unwieldy. When that happens, there is often commonalities. So instead of every SystemInterfacer subclass being a direct subclass, you can make a new class called AbstractXMLSystemInterfacer. All the XML SystemInterfacers subclass that. Since it contains code that is common to all the XML systems you deal with, you can save duplication and prevent bugs.

When you have something that matches well to objects and inheritance, it's a great tool. It can make your life SO much easier.

OOP isn't always necessary

As I said, not everything needs OOP. Small programs can easily be made that wouldn't benefit from inheritance. I often write little tools to make automate some little process. These are usually one file, a few functions. The programs could even be much bigger. But if they only ever process one kind of "thing", OOP doesn't really add much over procedural code. Don't worry if you don't see how to make all your programs OOP... they just might not fit the OOP mould.

Conclusion

It took me a while to 'get' OOP because I tried to teach it to myself. I learned programming from books and tinkering before I could take programming classes, in C and Basic. The idea of objects and OOP was pretty foreign from how I was used to doing things, and I didn't have a lot of experience in the fist place. It wasn't until I started doing some non-trivial programming assignments (more than a few functions and one or two files) that asked me to use OOP that I really had a chance, and the utility of it really clicked.

Once I had a reason to use it, I got it pretty fast. As you use it in more and more assignments, you'll get it too. From my experience, and those of my classmates in school, it's not one of those things you can just read about and start applying immediately. It's a bit of a different, sort of a mindset or way of thinking.


4
[+5] [2010-01-10 00:37:11] dsimcha

Most things are easier to understand if you know at least a little about the abstraction layers directly above and directly below it. I never got OOP until I read a little about design patterns (a level of abstraction above most OOP tutorials; Head First Design Patterns is a good read) and a little about higher order functions, function pointers, virtual function tables, and data structures (a level below; how OOP works under the hood).

Also, in PHP the type system is so loose that OOP and polymorphism really isn't needed for flexibility the same way it is in, say, Java, C#, or C++. It's only useful for organization, which isn't really important in small projects.


+1 for design patterns. Read up on some of them and you may understand OO better - Erix
5
[+4] [2010-01-10 00:27:03] mmr

OOP is useful when you have large, complex systems that have many repeated operations that can be accumulated together into a simple reference.

If you're just doing something simple, something where a procedure would take 5 lines and you're probably never going to need it again, then OOP is most likely overkill. Too many people want to solve their problems by OOP, when it might not be the right call; just because you have a hammer does not mean that everything is a nail. Having an object that contains a single string, for instance, is pointless-- just use the string. Having an object that stores thirty strings and some numbers, not so pointless, because now you can treat all of that mess of data as the same thing for reading, writing, etc.

OOP is also useful if you want to get into patterns [1]. I never really understood OOP beyond the accumulation I just described until I figured out patterns. MVC [2] is the best way I've found to write the programs I write, and if you ever have to write a program that must produce auditable logs, the Mediator [3] pattern is the right thing to do.

[1] http://en.wikipedia.org/wiki/Design_patterns
[2] http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
[3] http://en.wikipedia.org/wiki/Mediator_pattern

6
[+3] [2010-01-10 00:10:41] Moshe

To directly answer your question:

I don't know how you think so I don''t know why it would be hard for you. I had trouble with OOP at first too. Some people have trouble understanding the analogies.

Another way to understand OOP is as follows:

Objects are nouns Methods can be understood as verbs Properties - Adjectives parameters/arguments - adverbs

Class Noun{

  Private adjective;

  Public function __construct(){

  }

  function verb(adverb){
    //do something
  }
}

Greate example! I don't have any probjem with OOP but it was very good idea!!! - Jalalx
Thanks. I have a friend who is also a programmer. He disagrees with this analogy. He says Commands are Verbs. Functions are groups of commands. Whatever. I think this works. - Moshe
7
[+3] [2010-02-13 16:27:27] JW.

I agree. I never understood those dog, cat telephone car analogies.

OOP, to me, is really a set of techniques to help fight the war against code-duplication.

I always thought 'Re-usability' was a luxury like a handy library or framework being shared from one project to another. But, no, it is vital to Don't Repeat Yourself within any project if you want to keep your sanity.

So, the 'noun objects' are really only a tiny aspect of OOP. OOP is really about eradicating repeated pieces of knowledge. See http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Also what really hit it home for me was when someone explained classes as responsibilities as opposed to things.

i.e

//responsible for cats
abstract class CatLover {
 protected $numberofcats;

 abstract public function takeCatToVetToGetSpayed()
} 

class Spinster extends CatLover {
 protected $numberofcats =100;

 public function takeCatToVetToGetSpayed() {
 //TODO
 }  
} 

etc.

8
[+3] [2010-11-19 01:33:39] manRo

Better OOP style for Form Class Example presented by hobodave would be somethink like that:

abstract class FormElement {
    protected $type;
    protected $name;
    protected $value;

    public function __construct($value = null) {
        $this->value = $value;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getType() {
        return $this->type;
    }

    public function getName() {
        return $this->name;
    }
}


class InputText extends FormElement {
    public $type = 'text';

    public function __toString() {
        return sprintf('<input value="%s" type="%s" name="%s">', $this->value, $this-  >type, $this->name);
    }
}

class Password extends InputText {
    public $type = 'password';
}

class Textarea extends FormElement {
    public $type = 'textarea';

    public function __toString() {
        return sprintf('<textarea name="%s"></textarea>', $this->type, $this->name);
    }

}

class Form {
    protected $inputs = array();
    protected $action;

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

    public function addElement(FormElement $FormElement) {
        $this->inputs[] = $FormElement;
    }

    public function __toString() {
        $form = '<form action="'.$this->action.'">';
        foreach($this->inputs as $FormElement)
            $form .= (string) $FormElement;

        $form .= '</form>';

       return $form;
    }
}

$Form = new form;
$Login = new InputText;
$Password = new Password;
$Form->addElement($Login);
$Form->addElement($Password);
echo $Form;

Like you see, now we have full power of OOP programming. We don't repeat ourselves just take a look on class Password that inherits from InputText that inherits from abstract class FormElement it has only one line in body but power of FormElement class + InputText class


9
[+2] [2010-01-10 00:27:48] orokusaki

Think of OOP as a way of extending the way we think about life into a program. Stuff doesn't just happen each day on its own, people, places, and things do actions, and create things, and that's why stuff happens. Say you want to write software to help people with real estate transactions. A person can buy a house for an amount of money and the ownership transfers to the person who bought it right. Let's analyze that:

Object: person
    attribute: age (extraneous)
Object: house
    attribute: value
Object: sale
    attribute: house (instance of house)
    attribute: amount (a general property expressed as a number)
    attribute: buyer (instance of person)
    attribute: seller (instance of person)

Now you could begin to code up a skeleton of objects in PHP with this analysis, something like this:

<?php

class Person {
    public $age = 50;

    public function buyHouseAndReturnSaleInstance($houseInstance)
    {
        $sale = new Sale();
        $sale->house = $houseInstance;
        $sale->amount = $someAmount;
        $sale->buyer = $this; // $this is a reference to the current instance of the class in which it is, so in this case it would reference the person object who is doing the buying.
        $sale->seller = $houseInstance->owner;
        $houseInstance->owner = $this;
        return $sale;
    }
}

class House {
    // This variable would be set dynamically in reality
    public $value = 50000;
}

class Sale {
    public $house = $instanceOfHouse;
    public $amount = 50000;
    public $buyer = $instanceOfPerson;
    public $seller = $anotherInstanceOfPerson;
}

?>

so in programming it helps to be able to analyze things in this way and write programs against that analysis.


I tend to not think about a "sale" as a "thing that does things". - jva
That's funny, where did I say that 'all' things do things? I said things do things. There's a program you can get called Hooked on Phonics for that. - orokusaki
10
[+2] [2010-05-19 18:21:39] bah

Take some PHP framework (I recommend CodeIgniter because of its weight and ease of use), then you'll be forced to learn OOP. It was hard for me to understand concepts of OOP at first, but now I'm starting to see benefits. It can be really hard to switch if you're used to procedural programming (it was hard for me too because I'm always sceptical about trying something new).


11
[+1] [2010-01-10 00:02:21] Steven

Here is an example:

  class Person 
  {
    private name;

    // This is the constructor. Here you can set default values when you create theobject.
    // In this demo I pass along a name when I create a new student.
    public function __construct($name) 
    {
      $this->name = $name;
    }

    public function getName()
    {
      return $this->name;
    }
  }

  $student = new Person('Oliver');
  echo $student->getName();

I use a class like this to create and display a gallery for my website.


12
[+1] [2010-01-10 00:23:03] el.pescado

Take a looka at some MVC framework such as CakePHP - it uses OOP extensively.

Using MVC frameworg is generally a good idea.


13
[+1] [2010-01-10 00:25:31] Milan Babuškov

Writing a class just to dump simple HTML is really not going to teach you much. I suggest you look into some MVC framework like CodeIgniter [1] in which you create classes for controllers and models. Once you create your first real controller class you will see how OOP can be used for something useful, like replacing all the if statements with class methods for example.

[1] http://www.codeigniter.com

14
[+1] [2010-01-10 01:07:08] Larry Watanabe

Because you're doing it in PHP where it was shoehorned in later.

Try playing around with SmallTalk to get a better feel for it, then you can apply the ideas in PHP.


(2) The language is almost never the problem when you are talking about programming-theory, especially not in this case. - Chacha102
(1) Chacha102: If that was true, Alan Kay wouldn't have had any reason to invent Smalltalk, and we could teach monads in 6502 assembly language (arguably simpler than Haskell). Languages do make concepts easier or harder to express (that's their purpose), and PHP is probably not the easiest language in which to express object-oriented programming. - Ken
15
[+1] [2010-01-11 11:11:57] Nachiket

You are right, real programming problems are not simple like Cat and Dog examples..

And the actual problem with Cat,Dog or similar examples in books/lectures shows only one concept at time. For example for explaining Inheritence: Cat extends/implements Animal , thats it. AND AFTER EXPLAINING EACH CONCEPT BOOK ENDS

Real problem comes when your Cat and Dog gets 4 legs and 2 ears and relationship like cat is afraid of Dog, dog loves dog, dog can eat cat. these is not covered in many books.. only few books explains it properly.

But OOP helps when you really understand it properly, and use it properly..which is hard... By the way.. You should read Head First: OOAD [1] book (its in Java, but concept explanation is very good) and book has 2 very practicle real world application not Cat/Dog 2 class application....

[1] http://headfirstlabs.com/books/hfooad/

16
[+1] [2010-02-02 07:07:36] serg

I was in exactly the same position as you. While knowing the theory I couldn't apply objects to my PHP code.

I would suggest starting with the simplest two kinds of classes such as classes that contain only member fields, and classes that contain only methods. Use only such classes and with time you will actually feel the need to have both fields and methods in a class, to extend classes and so on.

For example in usual procedural PHP site you have some data (probably as arrays) and some functions with this data. Simply convert your data to classes with only fields and use them as glorified arrays, and wrap your similar functions into classes and use them as utility classes. It sounds simple and trivial, but try it and you will be surprised how much you will learn and understand.


(1) Totally agree. Once you've had your fields and methods bundled together for a while, they start to feel really natural, and doing fancier things (like inheritance) makes much more sense to your brain. - MBCook
17
[0] [2010-01-10 06:16:06] Kevin

Many people fail to realize the benefits of OOP structure in PHP. In other languages, like Java and C#/VB.NET, it is much more explicit so you can totally see the benefit. Example:

interface IFormField
{
    function GetValue();
}

class TextBox
    implements IFormField
{
    function GetValue()
    {
        ...
    }
}

What does GetValue() return? String? Integer? Array? Even if it returns a String, you can subclass it and then change it to return an Integer. PHP allows you to do this.

In other languages such as Java and VB/C#.NET you could do something like:

public interface IFormField
{
    IFormFieldValue GetValue();
}

public class TextBox : IFormField
{
    public IFormFieldValue GetValue()
    {
        ...
    }
}

So now we know exactly what GetValue() returns. When extending the TextBox class, the method signature must be the same so we can guarantee child classes will be consistent.

If you are working on small projects, you probably do not see the benefit of creates classes and such. When developing applications on larger teams, or if you outsource work, having code like this will save a lot of time.

As for classes taking up too much room, check this out:
What can you build in 600 lines of code? [1]

[1] http://www.codinghorror.com/blog/archives/001043.html

18
[0] [2010-05-19 18:28:22] Francisco Garcia

OOP is hard for you because PHP does not force you to write 100% OOP and it is very tempting to start cheating... and then learning OOP takes way longer

You need practice with 100% OOP languages. C++ is not a good choice because you can still cheat and ignore it. Java is not 100% pure but when I used it, I immediately noticed that the only way to write a good Java program is using OOP. Smalltalk is more pure!

Just try to do some small projects with Java and learn UML along some patterns. UML is not necessary to learn OOP but it helps a lot to stick the idea to your head and start thinking in that way.


19