Необходимость абстрактного класса, а также интерфейса?

Интерфейс представляет собой 100% абстрактный класс, поэтому мы можем использовать интерфейс для эффективного программирования. Есть ли ситуация, когда абстрактный класс лучше, чем интерфейс?

Ответы

Ответ 1

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

Интерфейсы также не могут содержать.

Ответ 2

Да, есть место как для абстрактных классов, так и для интерфейсов.

Перейдем к конкретному примеру. Мы рассмотрим, как сделать CheckingAccount и SavingsAccount из абстрактного AbstractBankAccount и посмотреть, как мы можем использовать интерфейс, чтобы дифференцировать два типа учетных записей.

Чтобы начать, здесь абстрактный класс AbstractBankAccount:

abstract class AbstractBankAccount
{
    int balance;
    public abstract void deposit(int amount);
    public abstract void withdraw(int amount);
}

У нас есть баланс счета как balance и два метода deposit и withdraw, которые должны быть реализованы подклассами.

Как мы видим, абстрактный класс объявляет структуру того, как следует определять банковские счета. Как упоминает @Uri в своем ответе, в этом абстрактном классе есть состояние, которое является полем balance. Это невозможно с интерфейсом.

Теперь пусть подкласс AbstractBankAccount сделает a CheckingAccount

class CheckingAccount extends AbstractBankAccount
{
    public void deposit(int amount)
    {
        balance += amount;
    }

    public void withdraw(int amount)
    {
        balance -= amount;
    }
}

В этом подклассе CheckingAccount мы реализовали два абстрактных класса - здесь ничего интересного.

Теперь, как мы можем реализовать SavingsAccount? Он отличается от CheckingAccount тем, что он будет интересоваться. Интерес может быть увеличен с помощью метода deposit, но опять же, это не так, как если бы клиент вкладывал свой интерес. Поэтому было бы более ясным, если бы у нас было другое средство для добавления денег на счет, в частности, для интереса, скажем, метода accrueInterest.

Мы могли бы непосредственно реализовать метод в SavingsAccount, но у нас может быть больше типов банковских счетов, которые могут получить интерес в будущем, поэтому мы можем захотеть создать интерфейс InterestBearing, который имеет метод accrueInterest:

interface InterestBearing
{
    public void accrueInterest(int amount);
}

Итак, теперь мы можем создать класс SavingsAccount, который может получить интерес, реализуя интерфейс InterestBearing:

class SavingsAccount extends AbstractBankAccount implements InterestBearing
{
    public void deposit(int amount)
    {
        balance += amount;
    }

    public void withdraw(int amount)
    {
        balance -= amount;
    }

    public void accrueInterest(int amount)
    {
        balance += amount;
    }
}

Теперь, если мы хотим сделать другой тип учетной записи, скажем, PremiumSavingsAccount, мы можем сделать подкласс AbstractBankAccount и реализовать интерфейс InterestBearing для создания другой процентной учетной записи.

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

Итак, действительно есть места, где и абстрактные классы, и интерфейсы сосуществуют и работают вместе в одной ситуации.

Ответ 3

Абстрактный класс v/s интерфейс - это одна тема, которая генерирует много любопытства/интереса/путаницы для любого, кто не знаком с Java, и хочет копать глубже.

В этой статье содержится подробное объяснение по этой теме.

Ответ 4

Есть несколько причин, почему вы можете предпочесть абстрактный класс, не содержащий реализации, по интерфейсу:

  • В процессе компиляции могут быть обнаружены определенные невозможные действия и операции экземпляра.
  • У вас есть возможность добавить конкретные методы в более позднюю версию.
  • Раньше существовало значительное преимущество в производительности много лет назад.
  • С очень неясной точки зрения безопасности вы не можете получить уже существующий класс для реализации методов, создав подкласс уже существующего класса и абстрактного класса.

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

Ответ 6

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

Используя интерфейсы в вашем API, пользователям (включая вас) становится проще писать тестовый код с вашими классами, поскольку вы можете использовать тестовые классы, которые, например, не зависят от внешних ресурсов или которые демонстрируют явные виды плохого, но сложного в симуляции в реальной жизни поведения.

Итак, java предоставляет интерфейс List и абстрактный базовый класс AbstractList для "минимизации усилий, необходимых для реализации" интерфейса...