Интерфейсы и динамический метод отправки
Обычное переопределение (без использования интерфейсов)
class A {
int x = 0;
void show() {
System.out.println("In A. x : " + x);
}
}
class B extends A {
void show() {
System.out.println("In B. x : " + x);
}
}
class C extends A {
void show() {
System.out.println("In C. x : " + x);
}
}
class Test {
public static void main(String args[]){
A obj = new B();
obj.show();
obj = new C();
obj.show();
}
}
Это то же самое, что делать это с интерфейсами:
interface A {
int x = 0;
void show();
}
class B implements A {
public void show() {
System.out.println("In B. x : " + x);
}
}
class C implements A {
public void show() {
System.out.println("In C. x : " + x);
}
}
class Test {
public static void main(String args[]){
A obj = new B();
obj.show();
obj = new C();
obj.show();
}
}
Вывод в обоих случаях будет одинаковым, и даже реализация будет аналогичной. Мой вопрос: зачем нужны интерфейсы, когда вы можете сделать то же самое, используя динамический метод диспетчеризации?
3 ответа
Есть несколько моментов для рассмотрения:
- Интерфейс дает возможность вашему классу расширяться с другим классом. Как вы знаете, вы не можете расширять несколько классов, но вы можете реализовать несколько интерфейсов (для достижения множественного наследования) .
- Расширяя класс, вы не можете заставить подкласс переопределять метод, определенный в суперклассе. В то время как в реализации интерфейса вынуждаете ваш метод реализовывать в подклассе.
- Это зависит от реализации того, что будет вашей потребностью. Вы хотите, чтобы подкласс должен был реализовать метод, а не использовать дизайн интерфейса, в то время как вы не будете беспокоиться о методе суперкласса с переопределением подкласса или о том, чем вы можете использовать дизайн расширений.
Я надеюсь, что это поможет вам понять разницу в дизайне.
Интерфейсы и суперклассы предназначены для разных случаев использования:
- суперклассы позволяют факторизовать общие методы (но в Java класс имеет только один родительский класс)
- интерфейсы объявляют константы и / или сигнатуры методов, но класс может реализовывать столько методов, сколько ему нужно
Интерфейсы необходимы при прокси, потому что прокси может только реализовывать интерфейс и не расширять классы. И прокси активно используются в таких средах, как Spring, для простого аспектно-ориентированного программирования.
Vikingsteve прав, но я добавлю немного больше деталей.
Существует различие между наследованием типов и наследованием реализации. В Java вы можете иметь множественное наследование типов, но не множественное наследование реализации.
Это означает, что класс может реализовывать несколько интерфейсов и наследовать тип от каждого из этих интерфейсов. Объект, созданный из этого класса, в основном относится ко всем этим типам одновременно. Но вы можете расширить только один другой класс и наследовать его реализацию.