TOC

This article has been localized into Russian by the community.

Классы:

Абстрактные классы

Абстрактные (abstract) классы особенные, т.к. для них нельзя создавать экземпляры. Вместо этого они обычно содержат функции, которые наследуются в новые классы. Поэтому они часто используются как базовые классы для какой-нибудь большой иерархии классов. В параграфе про наследование мы создали класс Animal (Животное), а затем класс Dog (Собака), который наследовался от Animal. В вашем проекте вы можете небезосновательно решить, что нельзя создавать экземпляры Animal, поскольку он слишком неконкретный, а можно использовать только классы-наследники. Тогда класс Animal будет базовым классом в вашем маленьком зоопарке.

Абстрактным может быть также отдельный метод. Но если вы отметите хотя бы одну функцию в классе как абстрактную, то и весь класс должен быть абстрактным - только абстрактные классы могут содержать абстрактные методы. Следующая особенность - абстрактные функции не содержат (и не могут содержать) никакого кода, это просто объявление. Они нужны лишь затем, чтобы принудить любой класс-наследник реализовать данную функцию и написать подходящий код. Иначе PHP выбросит ошибку. Тем не менее, абстрактные классы могут содержать не абстрактные методы, которые реализуют базовую функциональность в абстрактном классе. Давайте продолжим разбираться на примере абстрактного класса:

abstract class Animal
{
    public $name;
    public $age;
    
    public function Describe()
    {
        return $this->name . ", " . $this->age . " years old";    
    }
    
    abstract public function Greet();
}

Как вы можете видеть, класс выглядит как обычно, за исключением пары деталей. Первая - это ключевое слово abstract, которое отмечает и класс в целом, и последнюю функцию как абстрактные. Как уже упоминалось, абстрактная функция не может иметь тела (кода), так что она просто заканчивается точкой с запятой. Теперь давайте создадим наследника для нашего класса Animal:

class Dog extends Animal
{
    public function Greet()
    {
        return "Woof!";    
    }
    
    public function Describe()
    {
        return parent::Describe() . ", and I'm a dog!";    
    }
}

Как вы можете видеть, мы реализовали обе функции базового класса Animal. Функция Greet(), которую мы были обязаны реализовать, т.к. она была отмечена как абстрактная, - она просто возвращает слово/звук, свойственное данному виду животных. Мы не обязаны были реализовывать функцию Describe() - она уже реализована в класса Animal, но нам захотелось немного расширить ее функциональность. Здесь есть вкусная возможность - мы можем переиспользовать код, который уже реализовали в классе Animal, и добавить к нему, что захотим. В нашем случае мы используем ключевое слово parent (родитель), чтобы обратиться к классу Animal, а затем вызываем функцию Describe() из этого класса. После этого мы добавляем небольшой текст к результату, чтобы уточнить, о каком виде животного идет речь. Теперь давайте попробуем использовать этот новый класс:

$animal = new Dog();
$animal->name = "Bob";
$animal->age = 7;
echo $animal->Describe();
echo $animal->Greet();

Тут нет ничего загадочного. Мы просто создаем экземпляр класса Dog, задаем два его свойства и затем вызываем два метода, определенных в этом классе. Если вы протестируете этот код, то увидите, что метод теперь содержит комбинацию из версий для Animal и Dog, как мы и ожидали.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!