Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    Regular Coder funnymoney's Avatar
    Join Date
    Aug 2007
    Posts
    364
    Thanks
    17
    Thanked 24 Times in 24 Posts

    Abstract problem..

    I'm trying to implement abstract class to certain number of classes but i have simple problem with this piece of code

    PHP Code:
    abstract Class Implementations {
        
        public function 
    __construct() {
            
    $this->implementMain = new Main();
        }

    }

    Class 
    Main {
        public function 
    main() {
            return 
    "Do something in method main() class Main";
        }
    }

    Class 
    Sub extends Implementations {
        
        public function 
    sub() {
            return 
    $this->implementMain->main();
        }
        
    }
    $sub = new Sub;

    print(
    $sub->sub()); 
    while this sloppy code works

    PHP Code:

    abstract Class Implementations {
        
        public function 
    implementMain() {
            return new 
    Main();
        }
    }

    Class 
    Main {
        public function 
    main() {
            return 
    "Do something in method main() class Main";
        }
    }

    Class 
    Sub extends Implementations {
        
        public function 
    sub() {
            return 
    $this->implementMain()->main();
        }
        
    }
    $sub = new Sub;

    print(
    $sub->sub()); 

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    You have a bc (backwards compatibility) issue. There is nothing wrong with you're code, its the naming convention:
    PHP Code:
    Class Sub extends Implementations {
        
        public function 
    sub() {
            return 
    $this->implementMain->main();
        }
        

    Prior to PHP5, constructors used the naming convention of the class name. Since PHP uses caseless method and function names, the Sub::sub is considered its constructor therefore overriding the constructor declared in abstract implementation.
    Fix by either calling parent::__construct, by renaming the sub method, or by declaring an explicit __construct in sub that calls the parent::__construct. The recommended solution is to rename the sub to prevent bc break on PHP4.
    You should also be declaring you're $implementMain in abstract implementation. This is especially true since you're dealing with an object which simulates pass by reference using an object pointer (not quite the same as reference, but PHP doesn't actually support pointers anyway). So you have a public member that can be altered from any scope with any call which will create a privacy leak:
    PHP Code:
    abstract Class Implementations {
        
        protected 
    $implementMain;
        public function 
    __construct() {
            
    $this->implementMain = new Main();
        }


    Also, without any abstract methods inside of the abstract class, you may as well create a concrete class to extend off of.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    funnymoney (08-24-2009)

  • #3
    Regular Coder funnymoney's Avatar
    Join Date
    Aug 2007
    Posts
    364
    Thanks
    17
    Thanked 24 Times in 24 Posts
    ah.. now i get it...
    i edited my mistake where i tried again.. lol, i changed both class name Sub and method sub to same Subz and subz so then i've again overwritten constructor. lol

    Thanks!!!!

    And as for abstract methods, well first lemme ad this bit of abstraction to me classes, so then i can check out weather i can pull out even some abstract methods out of them.

    OOP is FUN

    one more question why did you add that protected $implementMain var, does it have any purpose, or you added it just to know that this class's construct creates that variable?
    Last edited by funnymoney; 08-24-2009 at 09:44 AM.

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    The naming is still the same. The class name cannot match the name of the method in use, otherwise it considers it the constructor.
    Scope resolution allows you to use parent and self refering to the object context rather than the static context (which is interesting since it technically applies to the static context as well).
    So if you override you're constructor, PHP requires an explict call to the parent constructor:
    PHP Code:
    class MyClass
    {
        public function 
    __construct()
        {
            print 
    'Hello world from: ' get_class($this);
        }
    }

    class 
    MyChild extends MyClass
    {
    }

    new 
    MyChild(); // Prints 'Hello world from: MyChild
    // On the other hand:
    class MyChild extends MyClass
    {
        public function 
    __construct()
        {
            print 
    'Goodbye';
        }
    }
    new 
    MyChild(); // Prints 'Goodbye'.

    class MyChild extends MyClass
    {
        public function 
    __construct()
        {
            
    parent::__construct();
            print 
    '.  Goodbye';
        }
    }
    new 
    MyChild(); // Prints 'Hello world from: MyChild.  Goodbye 
    A practical implementation for abstract models is a shape:
    PHP Code:
    abstract class Shape
    {
        
    // Add a whole pile of members
        
    public abstract function getArea();
    }

    class 
    Square extends Shape
    {
        private 
    $fDimension;
        public function 
    __construct($fDim)
        {
            
    $this->fDimension $fDim;
        }
        public function 
    getArea()
        {
            return 
    pow($this->fDimension2);
        }
        
    }

    class 
    Circle extends Shape
    {
        private 
    $fRadius;
        public function 
    __construct($fRadius)
        {
            
    $this->fRadius $fRadius;
        }
        public function 
    getArea()
        {
            return 
    M_PI pow($this->fRadius2);
        }
    }


    function 
    showArea(Shape $s)
    {
        
    printf("Area of %s is %0.5f\n"get_class($s), $s->getArea());
    }

    $s = new Square(4);
    $c = new Circle(3);

    showArea($s); // Area of Square is 16.0
    showArea($c); // Area of Circle is 28.26 
    Untested.

    That help?

    Edit:
    Snuck in an edit there you did :P
    protected $implementMain forces predeclaration of you're variables, which is good practice. On top of that, when an unrecognized variable is declared in a class (using just $this->var = whatever) and it has not been predeclared, it takes the scope of public. This actually bothers me to no end about PHP's handling of OO models. Anyway, protected is in use since public is too open and private restricts the child class' ability to view the declared member. Protected scope is defined as 'this' class and any of its subclasses.
    Last edited by Fou-Lu; 08-24-2009 at 10:01 AM.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    FWDrew (08-24-2009)

  • #5
    Regular Coder funnymoney's Avatar
    Join Date
    Aug 2007
    Posts
    364
    Thanks
    17
    Thanked 24 Times in 24 Posts
    Quote Originally Posted by Fou-Lu View Post
    Snuck in an edit there you did :P
    I was testing and testing, and rereading your post, then i figured out that PHP 4 glitch and edited me stupid class and method renaming

    for understanding abstract classes i will use Occam's razor . most simple solution is one that abstraction is used to force extended classes to use abstracted methods.

    other than that i can't see any other solution, and what's sad for me it doesn't solve me problem.

    i mean, it really isn't a problem, i was just looking for more elegant solution, but now it looks that there is no better solution than one i'm doing already.

    if you want to know what's it about here's the example

    PHP Code:
    <?php

    class Mainclass {
        
        public function 
    maindo() {
            return 
    "Mainclass::maindo()";
        }

    }

    Class 
    Firstclass  {
        public function 
    __construct($construct) {
            
    $this->mainclass = new Mainclass();
            
            
    $this->construct $construct;
        }
        
        public function 
    method() {
            return 
    $this->construct ." depends on "$this->mainclass->maindo() ."<br>\n";
        }
    }

    Class 
    Secondclass {
        public function 
    __construct($construct) {
            
    $this->mainclass = new Mainclass();
            
            
    $this->construct $construct;
        }
        
        public function 
    method() {
            return 
    $this->construct ." depends on "$this->mainclass->maindo() ."<br>\n";
        }
    }

    $x = new Firstclass("Firstclass");
    $y = new Secondclass("Secondclass");

    print 
    $x->method();
    print 
    $y->method();

    ?>


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •