"Helló, Amigo! Ma néhány felfedezést fogsz tenni. A mai téma – kérem a dobpergés – az interfészek. "

"Igen. Egy olyan csodálatos nap, hogy hazamegyek fürödni."

" Az interfész az absztrakció és a polimorfizmus gyermeke. Az interfész nagyon hasonlít egy absztrakt osztályhoz, ahol minden metódus absztrakt. Ugyanúgy van deklarálva, mint egy osztály, de a kulcsszóval. Íme néhány példa interface:

Kód Leírás és tények
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
1) A szó helyett classazt írjuk, interfacehogy .

2) Csak absztrakt módszereket tartalmaz (nem kell hozzáadni az absztrakt szót).

3) Valójában az interfészeken minden metódus nyilvános.

interface Element extends Drawable, HasValue
{
int getX();
int getY();
}
Egy interfész csak más interfészt örökölhet.

Sok szülői felülettel rendelkezhet.

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;
}

}
Egy osztály több interfészt is örökölhet (és csak egy osztályt). Ennek az öröklődésnek a megjelenítéséhez a kulcsszót használjuk  implements.

Az ChessItem osztályt absztraktnak nyilvánították: a rajzolás kivételével minden örökölt metódust megvalósított.

Más szóval, ChessItem egy absztrakt módszert tartalmaz:  draw().

"Érdekes. De miért van szükségünk interfészekre? Mikor használják őket?"

"Az interfészeknek két erős előnyük van az osztályokhoz képest:

1) A "metódusdefiníciók" elkülönítése a metódusmegvalósításoktól.

Korábban már mondtam, hogy ha engedélyezni szeretnéd, hogy más osztályok meghívják az osztályod metódusait, akkor meg kell jelölned őketpublic . Ha azt szeretné, hogy bizonyos metódusok csak a saját osztályunkból legyenek meghívva, akkor azokat meg kell jelölni private. Más szóval, az osztály metódusait két kategóriába osztjuk: „mindenki számára” és „csak nekem”.

Interfészekkel még jobban erősíthetjük ezt az elkülönülést. Készítünk egy speciális „mindenki számára” osztályt, amely egy második „csak nekem való osztályt” örököl majd. Ez kb így nézne ki:

Előtt
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;
 }
Után
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;
 }
}
Előtt
public static void main(String[] args)
{
 Student student =
               new Student("Alibaba");
 System.out.println(student.getName());
}
Után
public static void main(String[] args)
{
 Student student =
               new StudentImpl("Ali");
 System.out.println(student.getName());
}

Az osztályunkat két részre osztottuk: egy interfészre és egy osztályra, amely az interfészt implementálja.

– Szóval mi az előnye?

"Ugyanaz a felület implementálható (örökölhető) különböző osztályokkal. És minden osztálynak saját viselkedése lehet. Csakúgy, mint az ArrayList és a LinkedList a List interfész két különböző megvalósítása. "

Így nem csak a különböző implementációkat rejtjük el, hanem az implementációkat tartalmazó osztályokat is (csak mindenhol használhatunk interfészt a kódban). Ez lehetővé teszi, hogy a program futása közben nagyon rugalmasan lecseréljünk egyes objektumokat más objektumokra, és az objektum viselkedését az azt használó osztályok tudta nélkül változtassuk meg.

A polimorfizmussal kombinálva ez egy nagyon erős technika. Jelenleg korántsem egyértelmű, hogy miért kell ezt tennünk. Először több tucat vagy több száz osztályból álló programokkal kell találkoznia, hogy felmérje, hogyan könnyíthetik meg az interfészek az életét.

2) Többszörös öröklődés.

Java-ban minden osztálynak csak egy szülőosztálya lehet. Más programozási nyelvekben az osztályoknak gyakran több szülőosztálya is lehet. Ez nagyon kényelmes, de sok problémát is okoz.

A Java kompromisszumot kínál:   nem örökölhet több osztályt, de több interfészt megvalósíthat. Egy interfésznek több szülőfelülete is lehet.  Egy osztály több interfészt is megvalósíthat, és csak egy szülőosztályt örökölhet.