2014-01-24 23 views
0

Есть ли возможность вызвать метод классов расширений из конструктора базового класса?Метод вызова в классе расширения из конструктора базового класса

Вот пример того, что я хочу сделать:

<?php 
class SomeController extends Controller { 
    public function init() { 
     echo "lol"; 
    } 
} 

class Controller { 
    public function __construct() { 
     // do something to call init() in SomeController. 
    } 
} 

Просто интересно, что-то вроде этого возможно.

ответ

1

Суперклассы не могут ничего знать о своих подклассах, за исключением ограничений, являющихся подклассом суперкласса, налагаемого на подкласс. Если вы немного подумаете об этом, это имеет смысл. Как они могли? Разработчик мог бы добавить все, что захочет в подкласс в конце концов.

Однако, что суперкласс может выполнять, какие методы имеют подклассы. Если в суперклассе существует метод, он должен существовать в подклассе, потому что вы не можете удалить методы в подклассах. Если вы используете конкретный суперкласс в качестве базового класса, вам просто нужно реализовать метод, который ничего не делает в суперклассе, и все подклассы будут иметь его. Для любого подкласса, которому необходимо что-то произойти в этом методе, они могут переопределить его своей собственной реализацией. Вы можете вызвать метод из суперкласса и убедиться, что подкласс имеет его реализацию.

Для этого, метод не может быть закрытым. Он должен быть защищен или публично.

class Controller { 

    protected function init() { 
     // Do nothing, this method exists only to be overridden 
    } 

    public function __construct() { 
     // do something to call init() in SomeController. 
     $this -> init(); 
    } 
} 

Если это не имеет смысла для суперкласса существовать в своем собственном праве, то вы можете сделать суперкласс инициализации абстрактного метода, так что вы не должны обеспечить реализацию на всех. Вы можете объявлять абстрактные методы только в абстрактных классах, и абстрактные классы не могут быть созданы.

Любой подкласс, который наследуется от суперкласса, теперь будет вынужден реализовать метод init(). Если это не так, то при попытке запустить ваш код произойдет фатальная ошибка.

abstract class Controller { 

    abstract protected function init(); 

    public function __construct() { 
     // do something to call init() in SomeController. 
     $this -> init(); 
    } 
} 

Как и в предыдущем примере, это гарантирует, что все подклассы этого имеют метод Init(), и это поэтому безопасно вызывать Init() из суперкласса.

ПРИМЕЧАНИЕ. Из-за особенностей того, как реализован PHP Zend Engine, теоретически можно вызвать методы подкласса из суперклассов, когда суперкласс не знает о методе подкласса. Однако это не намеренное дизайнерское решение, это недокументированное поведение. Поэтому он может быть удален в любой момент. Даже если PHP остается таким навсегда, по-прежнему очень плохой практикой вызывать методы подкласса из суперкласса, не зная наверняка, что подкласс реализует этот метод. Никогда не зависеть от этого поведения.

Смежные вопросы