← Назад к вопросам

В чем разница между абстрактным классом и обычным классом?

2.2 Middle🔥 171 комментариев
#ООП

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные различия между абстрактным классом и обычным классом

Абстрактный класс и обычный класс (конкретный класс) — это ключевые концепции объектно-ориентированного программирования (ООП) в PHP, но они имеют фундаментальные различия в предназначении и использовании.

1. Цель и концепция

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

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

2. Возможность создания экземпляров

Самое очевидное различие:

  • Абстрактный класс нельзя инстанциировать напрямую. Попытка создать его объект приведёт к фатальной ошибке.
  • Обычный класс позволяет создавать экземпляры с помощью оператора new.
// Абстрактный класс - НЕЛЬЗЯ инстанциировать
abstract class Animal {
    abstract public function makeSound();
}

// $animal = new Animal(); // Fatal error: Cannot instantiate abstract class Animal

// Обычный класс - МОЖНО инстанциировать
class Dog {
    public function makeSound() {
        return "Гав!";
    }
}

$dog = new Dog(); // Успешное создание объекта
echo $dog->makeSound(); // Гав!

3. Наличие абстрактных методов

  • Абстрактный класс может содержать абстрактные методы (методы без тела, только сигнатура), помеченные ключевым словом abstract. Класс, содержащий хотя бы один абстрактный метод, обязан быть объявлен как абстрактный.
  • Обычный класс не может содержать абстрактных методов. Все его методы должны иметь реализацию.
abstract class Shape {
    // Абстрактный метод - без реализации
    abstract public function calculateArea();
    
    // Обычный метод с реализацией
    public function describe() {
        return "Это геометрическая фигура";
    }
}

class Circle extends Shape {
    private $radius;
    
    public function __construct($radius) {
        $this->radius = $radius;
    }
    
    // ОБЯЗАТЕЛЬНАЯ реализация абстрактного метода
    public function calculateArea() {
        return pi() * pow($this->radius, 2);
    }
}

// Обычный класс - все методы реализованы
class Rectangle {
    private $width, $height;
    
    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }
    
    // Все методы имеют реализацию
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

4. Использование в иерархии наследования

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

5. Практические применения

Когда использовать абстрактный класс:

  1. Когда несколько родственных классов должны следовать общему контракту (иметь одинаковые методы).
  2. Когда нужно предоставить базовую реализацию некоторых методов, но оставить часть функциональности для определения в дочерних классах.
  3. Для реализации паттерна Template Method, где абстрактный класс определяет "скелет" алгоритма.

Когда использовать обычный класс:

  1. Для создания конкретных объектов, которые можно напрямую инстанциировать.
  2. Когда класс является самостоятельной сущностью без необходимости задания контракта для наследников.
  3. Для простых сервисов, DTO-объектов, моделей данных.

6. Пример архитектурного различия

// Абстрактный класс как основа иерархии
abstract class DatabaseConnection {
    protected $connection;
    
    // Абстрактный метод - каждый тип БД реализует по-своему
    abstract public function connect();
    
    // Общий метод для всех наследников
    public function disconnect() {
        if ($this->connection) {
            // общая логика отключения
            $this->connection = null;
        }
    }
    
    // Шаблонный метод
    public function query($sql) {
        $this->connect();
        // выполнение запроса
        $this->disconnect();
    }
}

class MySQLConnection extends DatabaseConnection {
    public function connect() {
        // Специфичная реализация для MySQL
        $this->connection = new mysqli("localhost", "user", "pass", "db");
    }
}

class PostgreSQLConnection extends DatabaseConnection {
    public function connect() {
        // Специфичная реализация для PostgreSQL
        $this->connection = pg_connect("host=localhost dbname=db user=user");
    }
}

// Обычный класс - самостоятельная сущность
class UserService {
    private $dbConnection;
    
    public function __construct(DatabaseConnection $db) {
        $this->dbConnection = $db;
    }
    
    public function getUser($id) {
        return $this->dbConnection->query("SELECT * FROM users WHERE id = $id");
    }
}

7. Ключевые технические отличия

АспектАбстрактный классОбычный класс
ИнстанциированиеЗапрещеноРазрешено
Абстрактные методыМожет содержатьНе может содержать
Модификатор abstractОбязателен в объявленииНе используется
ЦельСоздание контракта, шаблонаСоздание конкретных объектов

Заключение

Основная философская разница заключается в том, что абстрактный класс определяет "что должно быть" (контракт), но часто не определяет "как именно" (реализацию), в то время как обычный класс предоставляет законченную реализацию, готовую к использованию. В практике разработки абстрактные классы используются для построения расширяемых архитектур, соблюдения принципа открытости/закрытости (Open/Closed Principle) и уменьшения дублирования кода через вынесение общей логики в родительский класс.