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

«В чем разница между абстрактным классом и интерфейсом?» — вопрос из категории ООП, который задают на 45% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В контексте автоматизации тестирования на Java (или C#) я использую и абстрактные классы, и интерфейсы для построения гибкой и поддерживаемой фреймворка.

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

  • Зачем в тестах: Для создания базового класса теста, который содержит общую логику (настройку/сброс драйвера, логирование), которую наследуют все конкретные тест-классы.

Интерфейс — это контракт, который определяет только сигнатуры методов (и, начиная с Java 8, default и static методы), но не их реализацию. Класс может реализовывать несколько интерфейсов.

  • Зачем в тестах: Для определения общего поведения (например, интерфейс WebActions с методами click(), typeText()), которое по-разному реализуется для Web, Mobile или API-тестов, обеспечивая полиморфизм.

Пример в Java для фреймворка тестирования:

// Интерфейс для поведения драйвера
interface BrowserActions {
    void openUrl(String url);
    WebElement findElement(By locator);
}

// Абстрактный класс с общей инфраструктурой
abstract class BaseTest {
    protected WebDriver driver;

    @BeforeEach
    public void setUp() {
        driver = new ChromeDriver(); // Общая настройка
    }

    protected void takeScreenshot(String name) {
        // Общая реализация скриншота
    }

    @AfterEach
    public void tearDown() {
        driver.quit(); // Общая очистка
    }
}

// Конкретный тест-класс
class LoginTest extends BaseTest implements BrowserActions {
    // Должен реализовать методы из BrowserActions
    public void openUrl(String url) { driver.get(url); }
    public WebElement findElement(By locator) { return driver.findElement(locator); }

    @Test
    public void testValidLogin() {
        openUrl("https://example.com/login");
        // ... логика теста, использующая методы из BaseTest и BrowserActions
    }
}

Видео-ответы