PHP:覆盖子类的父类属性

标签 php class oop overriding

也许你知道一些“正确的方法”来覆盖子类方法的类属性

<?php
class A {
  public $option;
  public function __construct() {
    $this->option = array(1,2,3);
  }

  public function bb() {
    $obj = new B;
    $obj->aa();

    print_r($this->option);die;
  }
}

class B extends A {

  public function __construct() {
    parent::__construct();
  }

  public function aa() {
    $this->option[] = 4;
    //print_r($this->option);die;
  }
}

$obj3 = new A;
$obj3->bb();
?>

返回 Array ( [0] => 1 [1] => 2 [2] => 3 )没有来自方法的元素 aa()
是否可以从子类覆盖父类属性?

最佳答案

问题是你试图以一种根本不应该做的方式做某事。很难说出您正在尝试做什么,但希望如果您查看我的示例,它将向您展示正在发生的事情:

<?php

class BaseClass {
    /* If a property is public or protected it can be overriden in derived classes.
     * If you had made it private it wouldn't be changable in derived classes. 
     * If you make it also make it static then there is only one copy of it shared 
     * by all instances of the class (as well as those derived from it). */
    protected $option=array();

    public function __construct() {
        $this->option=array(1,2,3);
        /* We are in the base class so the reset() method doesn't exist yet.
         * This fails in this class: */
        // $this->reset();
    }
    /** Print the $option variable. */
    public function dump() {
        echo sprintf('<pre><b>%s</b> = ', get_class($this));
        print_r($this->option);
        echo "</pre>\n";
    }
}

class DerivedClass extends BaseClass {
    public function __construct() {
        parent::__construct();
        /* We have complete control over the variable BaseClass::$option from this class.
         * If we want to we can even make it a string instead of an array. */
        $this->option="I've overridden the option property.";
    }
    /** Reset the BaseClass::$option variable. */
    public function reset() {
        $this->option=array(1,2,3,4);
    }
}

/// Create a few test objects to play with
$objBase=new BaseClass();
$objDerived=new DerivedClass();

$objBase->dump(); // Display the base object data

/// If BaseClass::$option is public you can edit it directly here.
/// This may be easier but it is discouraged because it breaks OOP principals.
//$objDerived->option[]=5;

$objDerived->dump(); // Display the derived object data

$objDerived->reset(); // call a method which will change our data
$objDerived->dump(); // Display the derived object data again now

类提供了许多方法来进一步控制从当前类和外部派生的那些类可以看到的内容。这是通过使用 public、protected 和 private 关键字来完成的。当设置为 public 时,方法和属性对所有内容都是可见的,但它们仍然可能超出范围。简而言之,您遇到的唯一问题是您的方法 B:aa() 超出了 A::bb() 的范围。

请记住,实际上 BaseClass 可能与 DerivedClass 不在同一个文件中,并且某些项目可能不需要 DerivedClass。如果您牢记这一点,您就不能使用甚至没有加载到项目中的方法。

在您的代码中,您在方法 A::bb() 中创建了一个全新的 B 实例。这是一种设计模式,除了少数特定类型的函数(称为工厂函数,因为它们旨在有意从基类中创建派生类)之外,您几乎永远不会看到这种设计模式。我很确定这不是你在这里做的事情,因为这不是你在 PHP 中经常做的事情,因为 PHP 通常不从文件中读取二进制类数据,而在其他情况下,通常有更好的方法来完成工作。

关于PHP:覆盖子类的父类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22722670/

相关文章:

php - 从具有相同名称的多行中获取结果

Php 联系表,一直工作到迁移。警告 : mail() [function. 邮件] : Bad parameters to mail() function, 邮件未发送

swift - 在类中包含 NSDateFormatter 的问题

java - 在 for 循环中使用 continue : the order it produces

php - 如何在用户点击提交按钮时将数据发送回相同的表单

WCF 对象设计 - OOP 与 SOA

php - 在数据库中分别更新多个图像

php - 将数据插入 mysql 数据库表 : showing DB error 时出现问题

class - 在声明中或使用 init 初始化 Swift 类变量?

C++ 指向类方法的指针