【问题标题】:PHP OOP extend class or pass it as parameterPHP OOP 扩展类或将其作为参数传递
【发布时间】:2017-02-27 21:54:04
【问题描述】:

我有点糊涂了,好久,我都是这样使用PHP类的:

class A {
   private $temp;

   public function __construct() {
       for($i=0; $i<=300000; $i++) { $this->temp[ $i ] = "Nedzad Alibasic"; }
   }
}

然后是另一个在构造中包含参数的类,我会将 A 类作为声明的模型传递:

class B {
   private $a;
   public function __construct($a) { $this->a = $a; }
}

一切都很好,我可以很容易地通过$b-&gt;a-&gt;somefunction(); 引用class A,但在我看来,当我将 A 类分配给 B 时,我会收取额外的内存,因为我通过了整个类? 但是我怎么看呢,传递类和扩展类几乎没有区别?

我的意思是,在内存几乎没有差异的情况下,我为什么要从这种方式切换到class B extends A { /** code **/ }

或者还有其他有用的东西我可以与扩展一起使用,但不能在传递类中作为参数使用。

最好的问候。

【问题讨论】:

  • 扩展A会在A的基础上创建一个全新的类B。如果你传递A,它不会创建一个新版本的A,而是使用现有的实例作为参考。如果您随后将 A 传递给另一个类,例如 C,则 B 和 C 都将使用相同的 A 实例。因此,您采用哪种方式,取决于您的需要。
  • 我对自己的方式更满意,我想就是这样。我只需要确认我没有遗漏任何东西:D

标签: php class oop memory


【解决方案1】:

扩展而不是包装在类的属性中的优点是,当您扩展时,您是在说 B 也是 A 类型,这意味着在您的代码中任何需要 A 类的地方,B 都可以是如果 B 从 A 延伸,则使用。

<?php
class A {
    private $temp;

    public function __construct() {
        for($i=0; $i<=300000; $i++) { $this->temp[ $i ] = "Nedzad Alibasic"; }
    }

    public function getTemp(){
        return $this->temp;
    }
}

class B extends A{
    public function __construct() {
        parent::__construct();
    }
}

function showFirstElementOfTemp($object){
    if($object instanceof A){
        echo $object->getTemp()[0];
    }else{
        echo "Not an A";
    }
}

$b = new B();

showFirstElementOfTemp($b); //Outputs "Nedzad Alibasic"

如您所见,这是可行的,因为 B 是 A,并且在我们检查实例并确保我们具有 A 类型的函数中将 B 作为参数传递,B 也被接受。

除此之外,包装一个 A 以访问它的方法和属性是相同的,只是您不会获得继承所拥有的这种类型层次结构。

【讨论】:

  • 谢谢你的回答,你让我的眼睛开了一点。
  • 我有一个快速的问题,如果父母已经被宣布不在课堂上,child B 是否应该打电话给parent::__construct();?在调用class B 之前在index.php 的某个地方?
  • 如果你从继承另一个类的类中实现__construct() 方法,则不会调用其父类的上层构造,您需要使用parent 关键字手动执行此操作。这允许您覆盖构造函数父级或扩展它的功能。我不知道我是否正确回答了你。如果我回答错了,请澄清一下。
  • 我的意思是,如果我声明$a = new A(); 并在它之后,我调用$b = new B();,B 中是否应该有parent::__construct();,因为我之前调用了父级,并且它的构造已执行。或者我必须在每个扩展其父级的子级内部调用parent::__construct(); 才能正常工作。
  • 是的,因为它们是两个不同的实例,并且不共享相同的属性值。因此,当您声明 new A() 时,它不会对任何其他声明产生任何影响,即使对其他 As 或其他 B 也没有影响。因此,当您执行 new B() 时,您需要调用超级构造以具有与新 A 相同的值。
【解决方案2】:

你习惯做的是一种组合形式,而使用extend当然是继承。一般组成为preferred over inheritance。你可能应该继续做。有大量资源描述了composition versus inheritance 的优缺点;选择一个好的是棘手的,但我建议你阅读其中的一些。

【讨论】:

  • 感谢您的链接
猜你喜欢
  • 2012-11-13
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-13
相关资源
最近更新 更多