Jump to content

[SOLVED] Encapsulation, polymorphism, interfaces, wtf?


matthewhaworth

Recommended Posts

Ok, I'm new to the concept of object oriented programming, infact, i'm relatively new to programming, well, i'm not, but i've never done anything that can be regarded as outstanding.  Anyway, I tried wikipedia-ing these keywords and just got a load of jargon, can someone point me to a tutorial that explains these concepts, simply?

Link to comment
Share on other sites

http://www.phpfreaks.com/tutorials/150/0.php

 

Start there, post any questions.

 

Thanks a lot.  To help myself learn things, I teach them.. I was wondering if anyone could review my article on object oriented programming that I plan to expand into a full article once I have learnt everything.

 

http://matthewhaworth.wordpress.com.

 

It would be greatly appreciated.  KeeB, thanks once again for the link.  ;D

 

//PHP4
class Dog {

    var $hungry = 'hell yeah.';

    function eat($food){
        $this->hungry = 'not so much.';
    }
}

 

*copied from that tutorial.  I thought object oriented programming wasn't implemented until php5?

Link to comment
Share on other sites

Let’s start with a few keywords: object, class, inheritance, polymorphism, methods (functions :P), fields (states), abstraction, encapsulation

 

A correction: fields are not states. The 'state' of an object is represented by the values (or state, in case of aggregate objects) of it's properties.

 

Static methods can be used just like functions, independent of any object and their state. However, the static operator can also be used to reference functions overridden by a child class, within an instantiation. Static properties affect all objects of that 'type' (objects derived from that class, either directly or via a child).

 

If that doesn't help, please explain what exactly you do not understand. I'm here to help.

Link to comment
Share on other sites

Also, I can explain by a bit of an example. Take this (silly) static object

 

<?php

class Math {

   public static function Add($a, $b) {
        return (int) $a + (int) $b;
   }

}

//client code
print Math::Add(2, 5); # returns 7
// clasically, you would have had to go:
/*
$math = new Math();
$math->add(2, 5);
*/
?>

 

Since that function really doesn't need to maintain any state, or update any parts of the object, a static modifier is a good option :)

Link to comment
Share on other sites

Ah! So a static function means you don't have to initiate the class first? You can just like, nick off with it's function? Can you give me a practical example of when this would happen?

What I couldn't get my head around before is why use Math::Add(args) when you can use Math->Add(args) but now that I realise :: ,eans you don't have to initiate it, it makes perfect sense.  Thanks a lot :).

 

Now a concept, I just simply.. cannot even start to get my head around is interfaces... completely thrown me, perhaps it's because I'm too lost in the original definition of the word..

 

And also, yes, I should make it more clear the a field DEFINES a state..

Link to comment
Share on other sites

an interface is useful. they basically define what a class should look like

 

silly examples work

 

interface language{

public function sayHello();

public function sayGoodbye();

}

 

class english implements language{

public function sayHello(){ return "Hello";}

public function sayGoodbye(){ return "Goodbye"; }

}

 

class spanish implements language{

public function sayHello(){ return "Hola";}

public function sayGoodbye(){ return "adiós"; }

}

 

$e = new english();

$s = new spanish();

 

echo $e->sayHello(); \\Hello

echo $s->sayGoodbye();  \\adiós

 

i find it useful when using the factory pattern (something you'll ask about soon)

Link to comment
Share on other sites

So they're like an abstract class only define the style of a class? That's silly, how's that useful? A practical example?

 

And yea, I've heard about this factory pattern thing left right and centre, that also throws me lol.. I'm beginning to get interfaces and abstract classes now, just don't understand how they're useful, I've never had to inherit a class yet.. I know I'm hardly experienced but I've never thought that doing such a thing would help me..

Link to comment
Share on other sites

I just asked the same question in my thread!

 

I don't see how interfaces help except for creating a roadmap of sorts.  Other than that, I'm still slightly puzzled by the abstract factory, but I get the factory method -- it's pretty cool.  It's hard to grasp ... I'm struggling but feel like I'm getting there.  What I'm struggling at, actually, is how to incorporate it into my existing site.  If it's even possible or necessary.

Link to comment
Share on other sites

I just asked the same question in my thread!

 

I don't see how interfaces help except for creating a roadmap of sorts.  Other than that, I'm still slightly puzzled by the abstract factory, but I get the factory method -- it's pretty cool.  It's hard to grasp ... I'm struggling but feel like I'm getting there.  What I'm struggling at, actually, is how to incorporate it into my existing site.  If it's even possible or necessary.

 

Does that mean that I'm breaking rules or that we're both batting for the same information? lol.

Link to comment
Share on other sites

here is a simple example of an abstract factory

 

class shipping{

public static getShipping($company){

switch($company){

case 'fedex':

return new fedex()

break;

case 'usps':

return new usps();

break;

}

}

abstract function calculateCost();

protected function ourMarkup(){ return 2;}

}

 

class fedex extends shipping{

public function calculateCost(){

return 4 + $this->ourMarkup();

}

}

 

class usps extends shipping{

public function calculateCost(){

return 3 + $this->ourMarkup();

}

}

 

alright here is where it works for you. say you have a dropdown for the user to choose their shipping method, lets call the var $_POST['shipping']

 

$price = shipping::getShipping($_POST['shipping']); //$price now holds an instance of whatever shipping compnay and because you have abstract methods defined in the parent, you can call on those methods knowing that they exist in all of the returned children

 

echo $price->calculateCost(); //6 or 5 based on shipping method

 

Link to comment
Share on other sites

and the reason why they are in seperate classes (fedex, usps) and are extending shipping, is because they may have to do differnt things.

 

imagine if you have to integrate usps' api to get their latest rates and then you'd have to do the same for fexex. keeping them seperate, but requiring certain functionality, keeps things clean(er) and very easy to modify/remove/add

Link to comment
Share on other sites

Thanks a lot!

 

It makes wonderful sense now, but if that's an abstract factory what's a normal factory?

 

I doubt my questions will reach an end tbh.

 

no problem, we're here to help each other learn. im sure if you search my early posts you'd see more novice-type questions.

 

you can use a factory just like that, except that you dont have to extend the factory, just return instances of classes

Link to comment
Share on other sites

and the reason why they are in seperate classes (fedex, usps) and are extending shipping, is because they may have to do differnt things.

 

imagine if you have to integrate usps' api to get their latest rates and then you'd have to do the same for fexex. keeping them seperate, but requiring certain functionality, keeps things clean(er) and very easy to modify/remove/add

 

Thanks a lot. 

 

But I still don't understand why we use interfaces?  I understand what they do, they set out the rules of a class, but why do that?  I mean, if you've got any brains you'll know what should be in a class and what shouldn't anyway.

 

And if this is an abstract factory, then why is the class not abstract, because I mean, you can call the function "getShipping" from the class AND initiate the class, it's not abstract, to me the following example is just a regular factory pattern.  And why's it called a 'factory' pattern?

 


class shipping{
public static getShipping($company){
switch($company){
case 'fedex':
return new fedex()
break;
case 'usps':
return new usps();
break;
}
}
abstract function calculateCost();
protected function ourMarkup(){ return 2;}
}

class fedex extends shipping{
public function calculateCost(){
return 4 + $this->ourMarkup();
}
}

class usps extends shipping{
public function calculateCost(){
return 3 + $this->ourMarkup();
}
}

 

 

Link to comment
Share on other sites

But I still don't understand why we use interfaces?  I understand what they do, they set out the rules of a class, but why do that?  I mean, if you've got any brains you'll know what should be in a class and what shouldn't anyway.

 

Interfaces are all about "encapsulation".  They allow developers to be less concerned with the actual implementation of classes and shift their focus to the intended design.  Let's consider a somewhat practical database example.  Imagine that we've decided that our trivial database layer should have a query method and a connect method.  Let's also say that we want to add support for multiple relational database managers (RDBMS) i.e., MySQL, MSSQL, SQLite, etc.  We can start by conceptually defining the behavior of our database layer in an interface:

 

<?php
interface Database
{
  public function connect($host, $db, $un, $pw);
  public function query($sql);
}
?>

 

We might then create a MySQL class which implements our Database interface.

 

<?php
class MySQL implements Database
{
  public function connect($host, $db, $un, $pw)
  {
     // MySQL specific implementation
  }

  public function query($sql)
  {
     // MySQL specific implementation
  }
}
?>

 

In our client code we can make calls to the Database interface without knowing (or caring for that matter) how the code is being implemented, as long as the behaviors defined by the interface are being implemented.  Since the Database interface is  defined we can very easily create an MSSQL class which implements and the interface and substitute it for the MySQL class and not have to change any client code.

 

I hope this was of some help.  You can see an example of this in a PHP open source project I'm involved with: http://junction.googlecode.com/svn/trunk/Junction/Db/.  We allow seamless switching between PDO and ADODB DB abstraction layers via the use of interfaces.

 

Best,

 

Patrick

Link to comment
Share on other sites

Keep in mind, this is something I play around with when I am not developing ;)

 

Here's my implementation of what jim described above:

 

Interface

<?php

interface Database {

        function connect($connectionString, $userName, $password);
        function select_db($db);
        function query($q);
        function num_rows();
        function next();

}

?>

 

MySQL

<?php
@include_once("database.interface.php");
@include_once("sql.exception.php");

class MySQL implements Database {

        private $connection;
        private $resultSet = NULL;


        function MySQL ($host, $userName, $password) {
                if(!extension_loaded("mysql")) {
                        throw new SQLException("MySQL not loaded");
                }

                try {
                        $this->connect($host, $userName, $password);
                } catch (SQLException $e) {
                        die($e->message());
                }

        }

        public function connect($host, $userName, $password) {
                $this->connection = @mysql_connect($host, $userName, $password);
                if (!$this->connection) { 
                        throw new SQLException("Unable to connect." . mysql_error(), 1);
                }
        }

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

        public function query($q) {
                $this->resultSet = mysql_query($q);
                if (!$this->resultSet) {
                        throw new SQLException("Error executing SQL statement. Here's the error: " . mysql_error());
                        return false;
                }
                return $this->resultSet;
        }

        public function next() {
                //nothing yet
        }

        public function num_rows() {
                if($this->resultSet != NULL) {
                        return mysql_num_rows($this->resultSet);
                }
                throw new SQLException("No rows");
        }
}
?>

Link to comment
Share on other sites

But I still don't understand why we use interfaces?  I understand what they do, they set out the rules of a class, but why do that?  I mean, if you've got any brains you'll know what should be in a class and what shouldn't anyway.

 

Interfaces are all about "encapsulation".  They allow developers to be less concerned with the actual implementation of classes and shift their focus to the intended design.  Let's consider a somewhat practical database example.  Imagine that we've decided that our trivial database layer should have a query method and a connect method.  Let's also say that we want to add support for multiple relational database managers (RDBMS) i.e., MySQL, MSSQL, SQLite, etc.  We can start by conceptually defining the behavior of our database layer in an interface:

 

<?php
interface Database
{
  public function connect($host, $db, $un, $pw);
  public function query($sql);
}
?>

 

We might then create a MySQL class which implements our Database interface.

 

<?php
class MySQL implements Database
{
  public function connect($host, $db, $un, $pw)
  {
     // MySQL specific implementation
  }

  public function query($sql)
  {
     // MySQL specific implementation
  }
}
?>

 

In our client code we can make calls to the Database interface without knowing (or caring for that matter) how the code is being implemented, as long as the behaviors defined by the interface are being implemented.  Since the Database interface is  defined we can very easily create an MSSQL class which implements and the interface and substitute it for the MySQL class and not have to change any client code.

 

I hope this was of some help.  You can see an example of this in a PHP open source project I'm involved with: http://junction.googlecode.com/svn/trunk/Junction/Db/.  We allow seamless switching between PDO and ADODB DB abstraction layers via the use of interfaces.

 

Best,

 

Patrick

 

But if we took away the 'implements Database', it wouldn't make a blind bit of difference..would it? Can you add functions that don't exist in the interface? Is it not just a debugging technique?

 

I'd like to thank you for the elaborate definition.

Link to comment
Share on other sites

But if we took away the 'implements Database', it wouldn't make a blind bit of difference..would it? Is it not just a debugging technique?

 

Touche' :-p

 

You're right.  In loosely typed language such as PHP the usefulness of interfaces is not as apparent as they as it may be in a strongly typed language.  It is often the case that interfaces are used to solidify a design.  However, implementing a common interface in PHP allows you to do things with type hinting like:

 

<?php

$db1 = new MySql();
$db2 = new MsSql();

doSomethingWithDatabase($db1);
doSomethingWithDatabase($db2);

function doSomethingWithDatabase(Database $db) 
{
  // do something
}

?>

Link to comment
Share on other sites

But if we took away the 'implements Database', it wouldn't make a blind bit of difference..would it? Is it not just a debugging technique?

 

Touche' :-p

 

You're right.  In loosely typed language such as PHP the usefulness of interfaces is not as apparent as they as it may be in a strongly typed language.  It is often the case that interfaces are used to solidify a design.  However, implementing a common interface in PHP allows you to do things with type hinting like:

 

<?php

$db1 = new MySql();
$db2 = new MsSql();

doSomethingWithDatabase($db1);
doSomethingWithDatabase($db2);

function doSomethingWithDatabase(Database $db) 
{
  // do something
}

?>

 

Ah, so creating an interface is like defining a type? And when you implement that interface you're applying a type to the class meaning you can be specific of what types you're implementing.. as you've just demonstrated. 

 

As a side note, can you call a function before you've defined it ???  Or does PHP put functions higher in processing precedence or something?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.