Необходимость абстрактного класса, а также интерфейса?
Интерфейс представляет собой 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 интерфейса позволяет использовать более чистый источник.
Ответ 5
Еще одно:
В мире Java есть статья, описывающая использование интерфейса и абстрактных классов:
Проверьте эту статью на Java World
Ответ 6
В общем, интерфейсы описывают публичный API, который должен использовать ваш код, тогда как абстрактные базовые классы лучше всего хранить как деталь реализации, где можно хранить общий код или состояние, чтобы уменьшить дублирование в любых классах реализации.
Используя интерфейсы в вашем API, пользователям (включая вас) становится проще писать тестовый код с вашими классами, поскольку вы можете использовать тестовые классы, которые, например, не зависят от внешних ресурсов или которые демонстрируют явные виды плохого, но сложного в симуляции в реальной жизни поведения.
Итак, java предоставляет интерфейс List и абстрактный базовый класс AbstractList для "минимизации усилий, необходимых для реализации" интерфейса...