简体   繁体   中英

PHP Class Extends and Objects

I have a results.php and 2 classes, Dog which extends Pet class. The "fullDescription" method call is just returning null for the results (eg: "Description: Your pet is a named .")

What am I missing?

results.php:

    <?php
    //include('_includes/pet.class.php');
    include("_includes/dog.class.php");

?>
<?php

// COLLECT THE VALUES FROM THE FORM
$petType = $_POST["petType"];
$petName = $_POST["petName"];

// CREATE A NEW INSTANCE OF THE CORRECT TYPE
if ($petType == "dog")
{
    $myPet = new Dog();
    $myPet->breed = Dog::randomBreed();
}
else
{
    $myPet = new Cat();
    $myPet->breed = randomBreed();
}

// ASSIGN THE VALUE FROM THE FORM TO THE name PROPERTY OF THE PET OBJECT
$myPet->name = $petName;
$myPet->descriptor = Pet::randomDescriptor();
$myPet->color = Pet::randomColor();

?>

<div class="basic-grey">

<h1>Here's the information about your pet:</h1>

<p>Pet Name:  <?php echo $myPet->name; ?></p>
<p>Pet Name:  <?php echo $myPet->breed; ?></p>
<p>Pet Name:  <?php echo $myPet->color; ?></p>
<p>Pet Name:  <?php echo $myPet->descriptor; ?></p>
<p>Description: <?php echo $myPet->fullDescription(); ?> </p>

Pet Class

<?php

class Pet
{

    // DEFINE YOUR CLASS PROPERTIES HERE
    private $name;
    private $descriptor;
    private $color;
    private $breed;

    ///////// Getters Setters /////////
    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $this->name;
    }

    public function setDescriptor($descriptor) {
        $this->descriptor = $descriptor;
    }
    public function getDescriptor() {
        return $this->descriptor;
    }

    public function setColor($color) {
        $this->color = $color;
    }
    public function getColor() {
        return $this->color;
    }

    public function setBreed($breed) {
        $this->breed = $breed;
    }
    public function getBreed() {
        return $this->breed;
    }

    // DEFINE YOUR METHODS HERE
    public function fullDescription()
    {
        return "Your pet is a $this->descriptor $this->color $this->breed named $this->name.";
        //echo $myPet->getName();
    }

    public static function randomDescriptor()
    {
        // SET UP AN ARRAY OF VALUES
        $input = array("stinky", "huge", "tiny", "lazy", "lovable");

        // RETURN A SINGLE RANDOM ELEMENT FROM THE ARRAY
        return array_rand(array_flip($input), 1);
    }

    public static function randomColor()
    {
        // SET UP AN ARRAY OF VALUES
        $input = array("tan", "brown", "black", "white", "spotted");

        // RETURN A SINGLE RANDOM ELEMENT FROM THE ARRAY
        return array_rand(array_flip($input), 1);
    }
}
?>

Dog Class

<?php
include('pet.class.php');

//////////// DOG CLASS //////////////
class Dog extends Pet
{public static function randomBreed()
    {
        // SET UP AN ARRAY OF VALUES
        $input = array("german shepherd", "dachsund", "retriever", "labradoodle", "bulldog");

        // RETURN A SINGLE RANDOM ELEMENT FROM THE ARRAY
        return array_rand(array_flip($input), 1);
    }

}

?>

The problem is because of the following lines,

$myPet->breed = Dog::randomBreed();

and

$myPet->name = $petName;
$myPet->descriptor = Pet::randomDescriptor();
$myPet->color = Pet::randomColor();

You're trying to access private properities of class Pet . Plus, you didn't the assign property values using setter methods. The solution would be like this:

You cannot access private properties of a class from it's child class, or outside of the parent class. First declare them as protected properties:

class Pet
{

    // DEFINE YOUR CLASS PROPERTIES HERE
    protected $name;
    protected $descriptor;
    protected $color;
    protected $breed;

    // your code

}

and then on results.php page change those lines in the following way:

// your code

if ($petType == "dog")
{
    $myPet = new Dog();
    $myPet->setBreed(Dog::randomBreed());
}
else
{
    $myPet = new Cat();
    $myPet->setBreed(Cat::randomBreed());
}
$myPet->setName($petName);
$myPet->setDescriptor(Pet::randomDescriptor());
$myPet->setColor(Pet::randomColor());
echo $myPet->fullDescription(); 

In your Pet class you've set your properties to private which means they cannot be manipulated publicly (from within the application), and only from within the class in which they are set ( Pet in this case). Any reason for that?

Set them to public :

public $name;
public $descriptor;
public $color;
public $breed;

Here's the manual on OOP visibility . Discusses the differences between public , protected , private .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM