1. Vaardigheden
Om de voordelen van interfaces en waar ze te gebruiken beter te begrijpen, moeten we het hebben over wat meer abstracte zaken.
Een klasse modelleert meestal een bepaald object. Een interface komt minder overeen met objecten, en meer met hun capaciteiten of rollen.

Zaken als auto's, fietsen, motorfietsen en wielen kunnen bijvoorbeeld het beste worden weergegeven als klassen en objecten. Maar hun capaciteiten - zoals "Ik kan worden bereden", "Ik kan mensen vervoeren", "Ik kan staan" - worden beter gepresenteerd als interfaces. Hier zijn enkele voorbeelden:
Code | Beschrijving |
---|---|
|
Komt overeen met het vermogen om te bewegen |
|
Komt overeen met rijvaardigheid |
|
Komt overeen met de mogelijkheid om spullen te vervoeren |
|
De Wheel klas kan bewegen |
|
De Car klas kan dingen verplaatsen, berijden en vervoeren |
|
De Skateboard klas kan bewegen en bereden worden |
2. Rollen
Interfaces vereenvoudigen het leven van een programmeur aanzienlijk. Heel vaak heeft een programma duizenden objecten, honderden klassen, maar slechts een paar dozijn interfaces , dwz rollen . Er zijn weinig rollen, maar er zijn veel manieren om ze te combineren (klassen).
Het hele punt is dat je niet voor elke klas code hoeft te schrijven om met elke andere klas te communiceren. U hoeft alleen maar te communiceren met hun rollen (interfaces).
Stel je voor dat je een huisdierentrainer bent. Elk van de huisdieren waarmee je werkt, kan verschillende vaardigheden hebben. U krijgt een vriendschappelijke discussie met uw buurman over wiens huisdieren het meeste lawaai kunnen maken. Om de zaak op te lossen, zet je alle huisdieren die kunnen "spreken" op een rij en geef je ze het commando: Spreek!
Het maakt je niet uit wat voor dier ze zijn of welke andere vaardigheden ze hebben. Zelfs als ze een driedubbele achterwaartse salto kunnen maken. Op dit specifieke moment ben je alleen geïnteresseerd in hun vermogen om luid te spreken. Dit is hoe het eruit zou zien in code:
Code | Beschrijving |
---|---|
|
Het CanSpeak vermogen. Deze interface begrijpt het commando to speak , wat betekent dat het een overeenkomstige methode heeft. |
|
Dieren die deze functie hebben.
Om het begrip te vergemakkelijken, hebben we de klassennamen in het Engels gegeven. Dit is toegestaan in Java, maar het is hoogst onwenselijk.
|
|
En hoe geven we ze het bevel? |
Wanneer het aantal klassen in uw programma's de duizenden bereikt, zult u niet meer zonder interfaces kunnen leven. In plaats van de interactie van duizenden klassen te beschrijven, volstaat het om de interactie van enkele tientallen interfaces te beschrijven - dit vereenvoudigt het leven enorm.
En in combinatie met polymorfisme is deze aanpak over het algemeen een doorslaand succes.
3. De default
implementatie van interfacemethoden
Abstracte klassen kunnen variabelen en implementaties van methoden hebben, maar ze kunnen geen meervoudige overerving hebben. Interfaces kunnen geen variabelen of implementaties van methoden hebben, maar dat kan wel meerdere overerving hebben.
De situatie wordt uitgedrukt in de volgende tabel:
Vermogen / eigendom | Abstracte lessen | Interfaces |
---|---|---|
Variabelen | ✔ | ✖ |
Methode implementatie | ✔ | ✖ |
Meerdere erfenissen | ✖ | ✔ |
Sommige programmeurs wilden dus echt dat interfaces de mogelijkheid hadden om methode-implementaties te hebben. Maar de mogelijkheid hebben om een methode-implementatie toe te voegen, betekent niet dat er altijd een zal worden toegevoegd. Voeg het toe als je wilt. Of als je dat niet doet, doe het dan niet.
Bovendien zijn problemen met meervoudige overerving voornamelijk te wijten aan variabelen. Dat hebben ze in ieder geval besloten en gedaan. Vanaf JDK 8 introduceerde Java de mogelijkheid om methode-implementaties aan interfaces toe te voegen.
Hier is een bijgewerkte tabel (voor JDK 8 en hoger):
Vermogen / eigendom | Abstracte lessen | Interfaces |
---|---|---|
Variabelen | ✔ | ✖ |
Methode implementatie | ✔ | ✔ |
Meerdere erfenissen | ✖ | ✔ |
Nu kunt u zowel voor abstracte klassen als voor interfaces methoden met of zonder implementatie declareren. En dit is uitstekend nieuws!
In abstracte klassen moeten methoden zonder implementatie worden voorafgegaan door het abstract
trefwoord. U hoeft niets toe te voegen vóór methoden met een implementatie. Bij interfaces is het tegenovergestelde waar. Als een methode geen implementatie heeft, hoeft er niets te worden toegevoegd. Maar als er een implementatie is, dan default
moet het trefwoord worden toegevoegd.
Voor de eenvoud presenteren we deze informatie in de volgende kleine tabel:
Vermogen / eigendom | Abstracte lessen | Interfaces |
---|---|---|
Methoden zonder implementatie | abstract |
– |
Methoden met een implementatie | – | default |
Probleem
Het gebruik van interfaces die methoden hebben, kan grote klassenhiërarchieën aanzienlijk vereenvoudigen. InputStream
De samenvatting en klassen kunnen bijvoorbeeld OutputStream
worden gedeclareerd als interfaces! Hierdoor kunnen we ze veel vaker en veel handiger gebruiken.
Maar er zijn al tientallen miljoenen (miljarden?) Java-klassen in de wereld. En als je standaardbibliotheken gaat veranderen, maak je misschien iets kapot. Alles leuk vinden! 😛
Om bestaande programma's en bibliotheken niet per ongeluk kapot te maken, werd besloten dat methode-implementaties in interfaces de laagste overervingsprioriteit zouden hebben .
Als een interface bijvoorbeeld een andere interface overerft die een methode heeft, en de eerste interface declareert dezelfde methode maar zonder een implementatie, dan zal de methode-implementatie van de overgeërfde interface de overervende interface niet bereiken. Voorbeeld:
interface Pet
{
default void meow()
{
System.out.println("Meow");
}
}
interface Cat extends Pet
{
void meow(); // Here we override the default implementation by omitting an implementation
}
class Tom implements Cat
{
}
De code wordt niet gecompileerd omdat de Tom
klasse de methode niet implementeert meow()
.
GO TO FULL VERSION