Menu
Coddy logo textTech

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

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 25 из 91.

Абстрактный класс — это класс, экземпляр которого нельзя создать напрямую. Он служит шаблоном для других классов, определяя методы, которые должны реализовать дочерние классы. Вы создаете абстрактный класс, используя ключевое слово abstract.

<?php
abstract class Shape {
    protected $color;
    
    public function __construct($color) {
        $this->color = $color;
    }
    
    abstract public function calculateArea();
    
    public function getColor() {
        return $this->color;
    }
}

class Rectangle extends Shape {
    private $width;
    private $height;
    
    public function __construct($color, $width, $height) {
        parent::__construct($color);
        $this->width = $width;
        $this->height = $height;
    }
    
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();

Вывод:

15

Класс Shape объявляет абстрактный метод calculateArea() без предоставления реализации. Любой класс, расширяющий Shape, должен реализовать этот метод. Обратите внимание, что абстрактные классы также могут содержать обычные методы, такие как getColor(), которые дочерние классы наследуют напрямую.

Абстрактные методы определяют, что должен делать дочерний класс, но не то, как он это делает. Это гарантирует, что у всех фигур будет метод calculateArea(), при этом позволяя каждой фигуре вычислять свою площадь по-разному.

Ключевой момент: Абстрактные классы сочетают в себе структуру наследования с обязательными требованиями. Используйте их, когда вы хотите разделить код между связанными классами, гарантируя при этом, что определенные методы будут реализованы каждым дочерним классом.

challenge icon

Задание

Легко

Давайте создадим систему медиаплеера, которая демонстрирует, как абстрактные классы обеспечивают соблюдение контракта, позволяя различным типам медиа реализовывать собственное поведение воспроизведения.

Вы организуете свой код в трех файлах:

  • Media.php — Определите абстрактный класс Media, который служит шаблоном для всех типов медиа. Он должен иметь защищенное свойство $title и конструктор, который принимает и устанавливает заголовок. Включите абстрактный метод с именем play(), который должны реализовать дочерние классы. Также добавьте обычный метод getTitle(), который возвращает заголовок — этот конкретный метод будет унаследован всеми дочерними классами.
  • Song.php — Определите класс Song, который расширяет Media. Подключите файл Media в начале. Этот класс добавляет свойство $artist. Конструктор должен принимать название и исполнителя — используйте parent::__construct() для названия, а затем сами установите исполнителя. Реализуйте обязательный метод play(), чтобы он возвращал "Playing song: [title] by [artist]".
  • Podcast.php — Определите класс Podcast, который расширяет Media. Подключите файл Media в начале. Этот класс добавляет свойство $episode (целое число). Конструктор должен принимать название и номер эпизода — используйте parent::__construct() для названия, а затем установите эпизод. Реализуйте обязательный метод play(), чтобы он возвращал "Playing podcast: [title] - Episode [episode]".

В main.php подключите файлы Song и Podcast. Вы получите четыре входных значения: название песни, имя исполнителя, название подкаста и номер эпизода (в виде строки для преобразования в целое число). Создайте объекты Song и Podcast с этими значениями. Выведите результат вызова play() сначала для песни, а затем для подкаста, каждый на новой строке.

Эта задача показывает, как абстрактные классы определяют контракт — каждый тип медиа должен иметь метод play(), но каждый тип реализует его по-своему. Абстрактный класс Media не может быть инстанцирован напрямую; он существует только для того, чтобы предоставить структуру и общую функциональность своим потомкам.

Шпаргалка

Абстрактный класс — это класс, экземпляр которого нельзя создать напрямую. Он служит шаблоном для других классов, определяя методы, которые должны реализовать дочерние классы. Используйте ключевое слово abstract для создания абстрактного класса.

abstract class Shape {
    protected $color;
    
    public function __construct($color) {
        $this->color = $color;
    }
    
    abstract public function calculateArea();
    
    public function getColor() {
        return $this->color;
    }
}

Дочерние классы должны реализовать все абстрактные методы:

class Rectangle extends Shape {
    private $width;
    private $height;
    
    public function __construct($color, $width, $height) {
        parent::__construct($color);
        $this->width = $width;
        $this->height = $height;
    }
    
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

Основные характеристики:

  • Абстрактные классы не могут быть инстанцированы напрямую
  • Абстрактные методы не имеют реализации в абстрактном классе
  • Дочерние классы должны реализовать все абстрактные методы
  • Абстрактные классы могут содержать как абстрактные, так и обычные методы
  • Обычные методы в абстрактных классах наследуются дочерними классами

Попробуйте сами

<?php
require_once 'Song.php';
require_once 'Podcast.php';

// Чтение входных данных
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));

// TODO: Создать объект Song с songTitle и artistName

// TODO: Создать объект Podcast с podcastTitle и episodeNumber

// TODO: Вывести результат вызова play() для песни

// TODO: Вывести результат вызова play() для подкаста

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование