【问题标题】:PHP Class Extends and ObjectsPHP 类扩展和对象
【发布时间】:2016-08-26 09:28:06
【问题描述】:

我有一个 results.php 和 2 个类,Dog 扩展了 Pet 类。 “fullDescription”方法调用只是为结果返回 null(例如:“Description: Your pet is a named .”)

我错过了什么?

结果.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);
    }

}

?>

【问题讨论】:

  • 你在哪里定义Cat类?也许真正的问题在于它实际上从未调用new Dog(),而是调用您的条件的else,即new Cat()

标签: php class extends


【解决方案1】:

问题是由于以下几行,

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

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

您正在尝试访问 privatePet 的属性。另外,您没有使用 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(); 

【讨论】:

  • 可能值得注意的是,由于子类无法访问私有属性,因此当 OP 进行像 $myPet-&gt;name = $petName; 这样的分配时,他正在为类 @987654331 创建新的 public 属性@ 本身。如果父类中的属性name 受到保护,他会看到一个致命错误“无法访问受保护的属性”。
  • @DarraghEnright 你是对的。我从你的解释中理解了为什么 $myPet->descriptor;从应用程序调用时返回值并且不从类方法返回任何内容 - eval.in/563116
  • @DarraghEnright 你说得对。由于无法从子类访问private 属性,因此应将所有属性声明为protected 以使它们可以从子类访问。接得好。 :-)
  • 没问题。很好的答案:)
  • 谢谢你的正能量。感谢您花时间回答!谢谢工作人员!
【解决方案2】:

在您的 Pet 类中,您已将属性设置为 private,这意味着它们不能公开(在应用程序内)和只能从在设置它们的类中(在这种情况下为Pet)。有什么理由吗?

将它们设置为public:

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

这是OOP visibility 的手册。讨论publicprotectedprivate之间的区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2017-04-17
    相关资源
    最近更新 更多