#7.13 php Переопределение методов базового класса. Модификаторы доступа при переопределении. Запрет переопределения (final)

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

Например, в классе Lion, порожденном на основе класса Animal, можно описать метод set_name, который будет преобразовывать буквы имени в заглавные.

public function set_name($text)
{
    $this->name = mb_strtoupper($text);
}

При вызове методы set_name объекта класса Lion будет вызван этот новый метод, что и подтверждает следующий пример.

Пример 1. Переопределение методов базового класса

<HTML>
    <HEAD>
        <TITLE>Перекрытие методов</TITLE>
    </HEAD>
    <BODY>
        <CENTER>
            <H1>
                Перекрытие методов
            </H1>
            <?php
                class Animal
                {
                    protected $name;
                    
                    public function set_name($text) 
                    {
                        $this->name = $text;
                        
                    }
                    
                    public function get_name() 
                    {
                        return $this->name;
                    }
                }
                
                class Lion extends Animal 
                {    
                    
                    public function roar() 
                    {
                        echo $this->name, " рычит! <BR>";
                    }
                    
                    public function set_name($text) 
                    {
                        $this->name = mb_strtoupper($text);
                    }
                }

                echo "Создание нового льва...<BR>";
                
                $lion  = new Lion();
                $lion->set_name("Бонифаций");
                echo $lion->roar();
            ?>
        </CENTER>
    </BODY>
</HTML> 

На рисунке 1 можно увидеть, что в результате выполнения примера 1 был вызван именно метод порожденного класса, а не базового.



Рис. 1. Перекрытие методов

Модификаторы доступа при переопределении свойств и методов базового класса

Аналогично методам, свойства базового класса также могут быть перекрыты одноименными свойствами производного класса. При переопределении метода или свойства в порожденном классе для этого метода или свойства должен быть указан такой же модификатор доступа, как в базовом классе, или менее строгий (табл. 1)

Таблица 1. Модификаторы доступа при переопределении

Модификатор доступа свойства/метода в базовом классе Допустимые модификаторы доступа для переопределенного свойства/метода производного класса
public public
protected public, protected
private public, protected, private

Например, если в базовом классе Animal метод set_name объявлен как public, то в производном классе Lion этот метод может быть объявлен только, как public. Если же мы попытаемся использовать для этого метода другой модификатор доступа, например,

class Lion extends Animal 
{    
    private function set_name($text) 
    {
        $this->name = mb_strtoupper($text);
    }
}

PHP сообщит об ошибке:
Fatal error: Access level to Lion::set_name() must be public (as in class Animal)

Ключевое слово final

Для того, чтобы запретить переопределение метода в производном классе, используется модификатор final:

class Animal
{
    protected $name;
                    
    public final function set_name($text) 
    {
        $this->name = $text;
                        
   }
                    
   public function get_name() 
   {
       return $this->name;
   }
}

При таком описании класса Animal попытка переопределить метод set_name в производном классе приведет к ошибке:

Fatal error: Cannot override final method Animal::set_name()

Чтобы запретить вообще наследование класса, ключевое слово final ставится перед определением этого класса:

final class Animal 
{
}
mariyas's picture

добавлено: модификаторы доступа при переопределении, ключевое слово final