当控制器类扩展父控制器时,为什么还需要父构造函数?

时间:2013-02-25 09:35:44

标签: php codeigniter class inheritance

我是CodeIgniter和OOP的初学者。我正在阅读CI教程页面here。我发现了一些在我脑海中提出问题的东西 看看这段代码:

<?php
class News extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
        $this->load->model('news_model');
    }

我认为如果我们创建了一个扩展CI_Controller的类,我们假设它必须在其父类中包含所有方法和属性(尽管我们可以覆盖它们)。那么,为什么代码中有parent::__construct();

5 个答案:

答案 0 :(得分:12)

__construct()是类的构造方法。如果您从中声明一个新的对象实例,它将运行。但是,它只运行自身的构造函数,而不是它的父元素。例如:

<?php

class A {
  public function __construct() {
    echo "run A's constructor\n";
  }
}

class B extends A {
  public function __construct() {
    echo "run B's constructor\n";
  }
}

// only B's constructor is invoked
// show "run B's constructor\n" only
$obj = new B();

?>

在这种情况下,如果在声明$ obj时需要运行A类的构造函数,则需要使用parent::__construct()

<?php

class A {
  public function __construct() {
    echo "run A's constructor\n";
  }
}

class B extends A {
  public function __construct() {
    parent::__construct();
    echo "run B's constructor\n";
  }
}

// both constructors of A and B are invoked
// 1. show "run A's constructor\n"
// 2. show "run B's constructor\n"
$obj = new B();

?>

在CodeIgniter的情况下,该行在CI_Controller中运行构造函数。该构造函数方法应该以某种方式帮助您的控制器编码。你只是想让它为你做好每一件事。

答案 1 :(得分:2)

扩展用于所有类。 __construct()用于您使用的那个类。

具有构造函数方法的类在每个新创建的对象上调用此方法,因此它适用于对象在使用之前可能需要的任何初始化。

答案 2 :(得分:2)

直接从Code Iginiter文档中回答您的问题:

  

这一行必要的原因是因为你的本地构造函数将覆盖父控制器类中的那个,所以我们需要手动调用它。

http://ellislab.com/codeigniter/user-guide/general/controllers.html#constructors

答案 3 :(得分:1)

我认为调用父构造函数/方法的需要是代码异味,称为 Call super 。除了错误敏感性(忘记这个调用,你可以得到意想不到的结果),它是程序而不是OOP。毕竟,陈述的顺序也可能导致意想不到的结果。

在此处阅读更多内容:https://martinfowler.com/bliki/CallSuper.html

答案 4 :(得分:0)

通过关键字extends使用继承。父类可以在调用其构造函数时设置一些值。如果未调用父构造函数,则不会设置值,并且子类将不会获取这些值。

示例:

class Super {
    protected $a;

    public function __construct(){
        $this->a = 'Foo';
    }
}

class Child extends Super{
    protected $b = 'Bar';

    public function __construct() {
        parent::__construct();
        echo $this->a;
    }
}

$x = new Child();

这里,如果未调用父构造函数,则类Child将不会回显任何内容。

因此,在Codeigniter中,当调用其构造函数时,父类可能会设置一些对其子项有帮助的值,并且如果调用父构造函数,这些值仅对其子项可用。