why do we still need parent constructor when contr

2019-04-06 12:59发布

问题:

I'm a beginner in CodeIgniter and OOP. I was reading a page of CI tutorial here. I found something that made a question in my mind.
Look at this code:

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

I think if we made a class that extends CI_Controller, we assume it must have all methods and properties in its parent class (Although we can override them). So, why there is parent::__construct(); in the code?

回答1:

__construct() is the constructor method of a class. It runs if you declare a new object instance from it. However, it only run the constructor of itself, not of its parent. For example:

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

?>

In this case, if you need to run class A's constructor when $obj is declared, you'll need to use 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();

?>

In CodeIgniter's case, that line runs the constructor in CI_Controller. That constructor method should have helped your controller codes in some way. And you'd just want it to do everythings for you.



回答2:

To answer your question directly from the Code Iginiter documentation:

The reason this line is necessary is because your local constructor will be overriding the one in the parent controller class so we need to manually call it.

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



回答3:

Extension used for all classes. __construct() used for that class that you use.

Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.



回答4:

I believe the need of calling the parent constructor/method is a code smell, known as Call super. Besides the error-sensitivity (forgetting this call, you can get unexpected results), it's procedural instead of OOP. After all, the order of statements can lead to unexpected results too.

Read more here: https://martinfowler.com/bliki/CallSuper.html



回答5:

Inheritance is being used via the keyword extends. The parent class could be setting some values when its constructor is being called. If the parent constructor is not called the values are not set and the child class will not get those values.

Example:

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();

Here, the class Child would echo out nothing if the parent constructor was not called.

So in Codeigniter the parent class is probably setting some values that are of help to its children when you call its constructor and those values are only available to its children if the parent constructor is called.