2016-05-01 170 views
0

我有一个result.php和2个类,Dog扩展了Pet类。 “fullDescription”方法调用仅返回null(例如:“Description:Your pet is a named。”)PHP类扩展和对象

我错过了什么?

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> 

宠物类

<?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); 
    } 
} 
?> 

狗类

<?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); 
    } 

} 

?> 
+0

你在哪里定义Cat类?也许真正的问题在于它从来没有实际调用过新的Dog(),而是调用了你的条件的'else',这是'new Cat()'。 –

回答

1

的问题是由于以下的线,

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

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

你试图访问Petprivate爆破性质。另外,你没有使用setter方法赋值属性值。 解决方案会是这样的:

您不能从其子类或父类外部访问private的属性。首先声明为protected属性:

class Pet 
{ 

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

    // your code 

} 

,然后results.php页面变化以下列方式的那些行:

// 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(); 
+1

可能值得注意的是,由于私有属性对于子类是不可访问的,所以当OP做出如'$ myPet-> name = $ petName;'的分配时,他正在类Dog本身上创建新的_public_属性。如果父类中的属性'name'受到保护,他会看到一个致命错误“无法访问受保护的属性”。 –

+0

@Darragh确定你是对的。我明白从你的解释为什么$ myPet-> descriptor;从应用程序调用时返回值,并且不返回任何类方法 - https://eval.in/563116 – splash58

+0

@Darragh确定您没错。由于'private'属性不能从子类访问,因此所有属性都应声明为'protected'以使它们可以从子类访问。接得好。 :-) –

0

在你Pet类你设置你的属性private这意味着它们不能在设置它们的类中被公开地操作(来自应用程序内)和Pet in这个案例)。有什么理由呢?

将它们设置为public

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

这里有OOP visibility手册。讨论公开,保护,私人之间的差异。