"Hej, Amigo! Idag ska du göra några upptäckter. Ämnet för idag - trumslag, tack - är gränssnitt. "

"Japp. En dag så underbar att jag är på väg hem för att ta ett bad."

" Ett gränssnitt är barnet till abstraktion och polymorfism. Gränssnittet är mycket likt en abstrakt klass där alla metoder är abstrakta. Det deklareras på samma sätt som en klass, men med nyckelordet . Här är några exempel: interface"

Koda Beskrivning och fakta
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
1) Istället för ordet classskriver vi interface.

2) Den innehåller endast abstrakta metoder (du behöver inte lägga till ordet abstrakt).

3) Faktum är att alla metoder på gränssnitt är offentliga.

interface Element extends Drawable, HasValue
{
int getX();
int getY();
}
Ett gränssnitt kan bara ärva andra gränssnitt.

Du kan ha många föräldragränssnitt.

class abstract ChessItem implements Drawable, HasValue
{
private int x, y, value;

public int getValue()
{
return value;
}

public int getX()
{
return x;
}

public int getY()
{
return y;
}

}
En klass kan ärva flera gränssnitt (och bara en klass). För att visa detta arv använder vi nyckelordet  implements.

Klassen ChessItem förklarades abstrakt: den implementerade alla ärvda metoder utom draw.

Innehåller med andra ord ChessItem en abstrakt metod:  draw().

"Intressant. Men varför behöver vi gränssnitt? När används de?"

"Gränssnitt har två starka fördelar jämfört med klasser:"

1) Separation av "metoddefinitioner" från metodimplementeringar.

Jag har tidigare sagt till dig att om du vill tillåta andra klasser att anropa metoderna i din klass, måste du markera dem sompublic . Om du vill att vissa metoder endast ska anropas från din egen klass, måste de markeras private. Med andra ord, vi delar in klassens metoder i två kategorier: «för alla» och «bara för mig».

Vi kan använda gränssnitt för att stärka denna separation ännu mer. Vi kommer att göra en speciell "klass för alla" som kommer att ärva en andra "bara-för-mig-klass". Det skulle se ut ungefär så här:

Innan
class Student
{
 private String name;

 public Student(String name)
 {
  this.name = name;
 }

 public String getName()
 {
  return this.name;
 }

 private void setName(String name)
 {
  this.name = name;
 }
Efter
interface Student
{
 public String getName();
}

class StudentImpl implements Student
{
 private String name;
 public StudentImpl(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 private void setName(String name)
 {
  this.name = name;
 }
}
Innan
public static void main(String[] args)
{
 Student student =
               new Student("Alibaba");
 System.out.println(student.getName());
}
Efter
public static void main(String[] args)
{
 Student student =
               new StudentImpl("Ali");
 System.out.println(student.getName());
}

Vi delar upp vår klass i två delar: ett gränssnitt och en klass som implementerar gränssnittet.

"Så vad är fördelen?"

"Samma gränssnitt kan implementeras av (ärva) olika klasser. Och varje klass kan ha sitt eget beteende. Precis som ArrayList och LinkedList är två olika implementeringar av List-gränssnittet. "

Således gömmer vi inte bara de olika implementeringarna, utan även klasserna som innehåller implementeringarna (vi kan bara använda gränssnitt överallt i koden). Detta låter oss mycket flexibelt ersätta vissa objekt med andra objekt medan programmet körs, vilket ändrar ett objekts beteende utan att veta om någon av klasserna som använder det.

I kombination med polymorfism är detta en mycket kraftfull teknik. Just nu är det långt ifrån självklart varför vi skulle behöva göra detta. Du måste först stöta på program som består av dussintals eller hundratals klasser för att förstå hur gränssnitt avsevärt kan förenkla ditt liv.

2) Multipelt arv.

I Java kan varje klass bara ha en överordnad klass. I andra programmeringsspråk kan klasser ofta ha flera överordnade klasser. Detta är väldigt bekvämt, men det skapar också många problem.

Java erbjuder en kompromiss:   du kan inte ärva flera klasser, men du kan implementera flera gränssnitt. Ett gränssnitt kan ha flera överordnade gränssnitt.  En klass kan implementera flera gränssnitt och ärva endast en överordnad klass.