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

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

2.0 Middle🔥 71 комментариев
#Java

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Разница между абстрактным и обычным классом в Java

Абстрактные классы и обычные классы — это два разных способа организации кода в Java. Их различие важно понимать при разработке и тестировании Java приложений, особенно при работе с фреймворками тестирования.

Обычный класс

Обычный класс (Concrete Class) — это полная реализация, которая может быть инстанцирована (создана).

public class Car {
    private String brand;
    private String model;
    
    public Car(String brand, String model) {
        this.brand = brand;
        this.model = model;
    }
    
    public void drive() {
        System.out.println("Car is driving");
    }
    
    public String getBrand() {
        return brand;
    }
}

// Можно создать объект
Car myCar = new Car("Toyota", "Camry");
myCar.drive();

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

Абстрактный класс (Abstract Class) — это класс, который содержит абстрактные методы (без реализации) и не может быть инстанцирован напрямую.

public abstract class Vehicle {
    private String brand;
    
    // Абстрактный метод (без реализации)
    public abstract void drive();
    
    // Обычный метод (с реализацией)
    public String getBrand() {
        return brand;
    }
}

// НЕПРАВИЛЬНО: Vehicle vehicle = new Vehicle();  // Ошибка компиляции!

Сравнительная таблица

ХарактеристикаОбычный классАбстрактный класс
ИнстанцированиеМожно создавать объектыНельзя создавать объекты
МетодыВсе с реализациейМогут быть без реализации
abstract методыНельзя иметьМогут быть
КонструкторыМогут быть publicТолько protected или private
НаследованиеМожно наследоватьсяДолжно наследоваться
Ключевое словоНе требуется abstractТребуется abstract
ИспользованиеПолная реализацияДоговор для подклассов

Абстрактные методы

Методы без реализации, которые должны быть переопределены в подклассах.

public abstract class APIClient {
    // Абстрактный метод
    public abstract Response sendRequest(String url, String method);
    
    // Обычный метод
    public void logRequest(String url) {
        System.out.println("Sending request to: " + url);
    }
}

public class RESTClient extends APIClient {
    // ОБЯЗАТЕЛЬНО реализовать абстрактный метод
    @Override
    public Response sendRequest(String url, String method) {
        // Реализация для REST
        return new Response(200);
    }
}

Практический пример для QA автоматизации

// Абстрактный класс как базис для различных тестов
public abstract class BaseTest {
    protected WebDriver driver;
    protected APIClient apiClient;
    
    // Общая подготовка
    @Before
    public void setUp() {
        driver = new ChromeDriver();
        apiClient = new RESTClient();
    }
    
    // Абстрактный метод, который должен быть реализован в подклассах
    public abstract void testScenario();
    
    // Общая очистка
    @After
    public void tearDown() {
        driver.quit();
    }
}

public class LoginTest extends BaseTest {
    @Override
    public void testScenario() {
        driver.get("https://example.com/login");
        // Реализация теста логина
        driver.findElement(By.id("username")).sendKeys("testuser");
    }
}

public class CheckoutTest extends BaseTest {
    @Override
    public void testScenario() {
        // Реализация теста оформления покупки
        driver.get("https://example.com/checkout");
    }
}

Интерфейсы vs Абстрактные классы

Абстрактный класс:

  • Может иметь состояние (поля)
  • Может иметь конструкторы
  • Может иметь методы с реализацией
  • Используется для "IS-A" отношений
public abstract class Shape {
    protected String color;  // Состояние
    
    public Shape(String color) {  // Конструктор
        this.color = color;
    }
    
    public abstract double getArea();  // Абстрактный метод
    
    public void display() {  // Конкретный метод
        System.out.println("Color: " + color);
    }
}

Интерфейс:

  • Только абстрактные методы (по умолчанию)
  • Нет состояния (только константы)
  • Нет конструкторов
  • Используется для "CAN-DO" отношений
public interface Drawable {
    void draw();  // Абстрактный метод
}

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

  • Есть общее состояние (поля) для всех подклассов
  • Нужны методы с разными уровнями доступа (private, protected)
  • Нужны нестатичные поля
  • Между подклассами связь IS-A
  • Логика будет меняться, но только в деталях

Когда использовать интерфейс

  • Нужно определить контракт без реализации
  • Несвязанные классы должны реализовать интерфейс
  • Нужна множественная реализация контракта
  • Связь CAN-DO, а не IS-A

Пример с тестированием API

// Абстрактный класс для базовых операций
public abstract class APITest {
    protected APIClient client = new RESTClient();
    
    protected Response makeRequest(String endpoint) {
        return client.get(endpoint);
    }
    
    public abstract void testEndpoint();  // Каждый тест реализует свой
}

public class UserAPITest extends APITest {
    @Test
    @Override
    public void testEndpoint() {
        Response response = makeRequest("/api/users");
        assert response.getStatus() == 200;
    }
}

Ключевые различия для практики

  1. Инстанцирование: new Car() работает, new Vehicle() — нет
  2. Наследование: class Car extends Vehicle работает
  3. Обязательность: Подклассы ДОЛЖНЫ реализовать все абстрактные методы
  4. Защита: Абстрактные классы обеспечивают шаблон для подклассов
  5. Гибкость: Обычные классы дают большую свободу реализации

Понимание этого различия критично для написания правильной архитектуры тестов и использования фреймворков тестирования, таких как TestNG и JUnit.

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