Статьи

Интерфейс и наследование в Java: интерфейс

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

Как определить:

Интерфейс может быть определен следующим образом:

public interface DriveCar { 
void turnLeft(); 
void turnRight();
void moveBack(); 
void accelerate();
}

Методы, объявленные в интерфейсе, не имеют тел методов. По умолчанию все методы интерфейса являются публичными абстрактными . Точно так же все переменные, которые мы определяем в интерфейсе, по существу являются константами, потому что они неявно являются публичными static final . Таким образом, следующее определение интерфейса эквивалентно приведенному выше определению.

 public interface DriveCar { 
public abstract void turnLeft(); 
public abstract void turnRight(); 
public abstract void moveBack(); 
public abstract void accelerate(); 
}

Как пользоваться:

Интерфейс определяет контракт, которому должен придерживаться реализующий класс. Приведенный выше интерфейс DriveCarCar Итак, класс, который фактически реализует интерфейс, должен реализовывать все методы, объявленные в интерфейсе.

Пример:

 class Car implements DriveCar{ 
void turnRight(){ 
//implementation code goes here 
} 

void turnLeft(){ 
//implementation code goes here 
}

void moveBack(){ 
//implementation code goes here 
}

void accelerate(){ 
//implementation code goes here 
}

}

Теперь мы можем взять ссылку типа DriveCarCar

Пример:

 DriveCar carDriver=new Car(); 
carDriver.turnLeft(); 
carDriver.moveBack(); 
//other method invocations 

Мы также можем кодировать следующим образом:

Пример:

 Car car=new Car(); 
car.turnLeft(); 
car.moveBack(); 
//other method invocations 

Зачем использовать интерфейсы:

Интерфейсы действуют как API (интерфейсы прикладного программирования). Давайте возьмем пример компании по обработке изображений, которая пишет различные классы для обеспечения функций обработки изображений. Таким образом, хорошим подходом будет создание интерфейсов, объявление методов в них и обеспечение их реализации классами. Таким образом, пакет программного обеспечения может быть доставлен клиентам, и клиенты могут вызывать методы, просматривая сигнатуры методов, объявленные внутри интерфейсов. Они не увидят фактическую реализацию методов. В результате реализация части будет секретом. Позже компания может принять решение о повторной реализации методов по-другому. Но клиенты обеспокоены только интерфейсами.

Интерфейсы предоставляют альтернативу множественному наследованию. Язык программирования Java не поддерживает множественное наследование. Но интерфейсы обеспечивают хорошее решение. Любой класс может реализовывать определенный интерфейс, и, что важно, эти интерфейсы не являются частью иерархии классов. Таким образом, общее правило — это продлить один, но реализовать много . Класс может расширять только один класс, но он может реализовывать множество интерфейсов. Итак, здесь у нас есть несколько типов для класса. Это может быть тип его суперкласса и всех интерфейсов, которые он реализует.

Пример:

Допустим, у нас есть два интерфейса A & B и два класса C & D.

 interface A{ } 
interface B{ } 
class C{ } 
class D extends C implements A,B { } 

Итак, мы можем иметь 3 типа для объекта класса D следующим образом:

 A a=new D(); B b=new D(); C c=new D(); 

Диаграмма классов

Но будь осторожен. Если вы используете интерфейс в качестве ссылочного типа и назначаете ему объект реализующего класса, тогда вы можете вызывать только те методы, которые объявлены внутри интерфейса. Это совершенно очевидно, потому что реализующий класс может определять свои собственные методы, которые не являются частью контракта между интерфейсом и классом. Итак, для вызова этих методов вы должны использовать класс в качестве ссылочного типа следующим образом:

D d=new D();

Расширение интерфейса:

Рассмотрим следующий сценарий. У вас есть интерфейс A и несколько классов реализации. Это определяет 2 метода.

 interface A{ 
int doThis(); 
int doThat(); 
} 

Теперь предположим, что вы хотите добавить еще один метод в интерфейс A:

 interface A{ 
int doThis(); 
int doThat(); 
int doThisAndThat(); 
} 

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

 interface APlusPlus extends A{
int doThisAndThat(); 
} 

Теперь ваши пользователи могут либо использовать старый интерфейс, либо перейти на новый интерфейс.

Замечания:

Любой класс, реализующий интерфейс, должен реализовывать методы, объявленные в этом интерфейсе, а также все методы, присутствующие в суперинтерфейсе.

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

Резюме:

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