1

Im taking a 3rd year module on webDesign focusing on OOP concepts which im struggling to master, but slowly getting there...

An Assignment Question Reads As Follows:

enter image description here

I coded thequestions above and I got the correct output but:

  1. I am unsure if the way I coded the greet() method in question A & B is correct? 2.The constructor and related properties inside the sub class for question B, I have my doubts whether those are correctly coded...even though I'm getting correct output, Please see comments in code
  2. I fail to see the benefit of extending the class, perhaps I don't see it because I Went about it the wrong way..?

Any advice appreciated, code follow below.

A)

class Animal{
    private $name;

    public function __construct($dogName){
        $this->name = $dogName;
    }//construct

    public function greet(){
        $sting = "Hello I'm some sort of animal and my name is .$this->name.";
        return $sting;
    }//function
}//class

$animal = new Animal('Jock');
echo $animal->greet();

B - SubClass

 class Dog extends Animal
    {
        private $animalType;

        public function __construct($animalType, $dogName){
            $this->$animalType = $animalType;
            $this->dogName = $dogName; //IS THIS LINE CORRECT, IF YES WHY SHOULD I USE IT AGAIN IN PARENT::_CONSTRUCT?

            //Call Animal Constructor To Finish
            parent::__construct($dogName);
        }//constructor

        public function greet($value1, $value2){
            $this->animalType = $value1;
            $this->dogName = $value2;
             $string = "Hello, I'm a ". $value1. " and my name is ". $value2;
            return $string;
        }
       }

$dog = new Dog('Dog', 'Jock');
echo $dog->greet('Dog', 'Jock');

4 Answers 4

1

Problems with your code:

1) Why would you have Dog::$animalType field? The purpose of extending generic Animal class is to make it rather specific with Dog subclass. Instead, just use strtolower(__CLASS__) for animal type.

2)Dog::greet() method doesn't need any arguments. It can clearly use $this->dogName.

3) You should name both name fields as Animal::$name and Dog::$name. That way, the sub-class will inherit from its parent class and override the values. Instead you have introduced additional field which does the same thing, and breaks the logical relation between parent and child classes.

4) Both parent and child classes should have same signatures for methods with the same name, so that inheritance could have a purpose. And since child classes inherit parent's classes as they are, there is no need to re-define them (in your case, the constructor).

class Animal
{
    private $name; // can't be private (unless you use a getter), if you want to extend it

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

    public function greet()
    {
        return "Hello I'm some sort of animal and my name is " . $this->getName();
    }

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

class Dog extends Animal
{
    public function greet()
    {
        return "Hello, I'm a " . strtolower(__CLASS__) . " and my name is " . $this->getName();
    }
}

$animal = new Animal('Cow');
echo $animal->greet();

$dog = new Dog('Max');
echo $dog->greet();
Sign up to request clarification or add additional context in comments.

3 Comments

Hi thank you for your answer, before I accept it would you mind giving me an alternative option to strtolower(__CLASS__) to put in the subclass if there is any alternative option?
Afraid not. Thing is, you generally don't use it like that: in large projects, during implementation of this kind of inheritances, you feed objects, rather than strings (for field "name" for example) and whole classes work through those objects. And instead of __CLASS__ you get to use the values from those objects.E.g., in a large codebase, some piece of code determines that some $user object has a field $user->pet which is object and has its own field $user->pet->type = dog. You feed that object to your class and it uses rather $user->pet 's fields automatically.
For your homework assignment, feel free just type in "dog" instead of using strtolower(). It can't be a big deal anyway. On the other hand, if it just said "animal" instead of "some sort of animal", you could easily have one "greet()" function and strtolower(__CLASS_) in it.
1

I think that the question is worded slightly incorrectly. I think that it wants you make the properties protected rather than private to extend the class (otherwise you would have to re-define the same properties in the subclass).

If this is the case, here is an example that shows class inheritance:

class Animal
{
    protected $name;

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

    public function greet()
    {
        return "Hello I'm some sort of animal and my name is {$this->name}.";
    }
}

$animal = new Animal('Jock');
echo $animal->greet();

class Dog extends Animal
{
    public function greet()
    {
        return "Hello I'm a dog and my name is {$this->name}.";
    }
}

$dog = new Dog('Jock');
echo $dog->greet();

You can see that we don't need to redefine the property $name and the constructor. The class Dog knows it's a dog, so we don't need to tell it that - we just adjust our greet method accordingly. This shows how we can access the protected property $name from Dog, and shows how we have overridden the greet method in Dog.

I hope this sheds some light on the subject.

Comments

1

I think you don't need the constructer in Dog class. The greet function looks wrong. I think you have to use the name from Animal class by using a name getter (getName).

class Animal
{
    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }//construct

    public function greet()
    {
        $sting = "Hello I'm some sort of animal and my name is " . $this->getName();
        return $sting;
    }//function

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

$animal = new Animal('Jock');
echo $animal->greet();

class Dog extends Animal
{
    public function greet()
    {
        $string = "Hello, I'm a dog and my name is " . $this->getName();
        return $string;
    }
}

$dog = new Dog('Jock');
echo $dog->greet();

2 Comments

Thank you @Timo but if you read the question, it says "the class must contain an appropriate method called Greet()" thus the way I interpreted the question is that you are only allowed to have one method in your Class But perhpas my interpretation is wrong...
Each class have their own Greet(). It's all how question requires them to be.
0

Another way of doing this

<?php
class Animal{
   protected $name;

    public function __construct($dogName){
        $this->name = $dogName;
    }//construct

    public function greet(){
        $sting = "Hello I'm some sort of animal and my name is .$this->name.";
        return $sting;
    }//function
}//class

$animal = new Animal('Jock');
echo $animal->greet();

class Dog extends Animal
    {
           private $animalType;
            public function __construct($animalType,$dogname){
             $this->animalType = $animalType;
             parent::__construct($dogname);     
            }

        public function greet(){

            echo  "Hello, I'm a ".$this->animalType. " and my name is ".$this->name;

        }
       }

$dog = new Dog('Dog', 'New Dog');
echo $dog->greet();

?>

2 Comments

Yes but the question clearly says you need to use a private property
In such case you can use get methods to access name in parent class and keep private proverty

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.