Elke nieuwe versie van Java verschilt van de vorige. Als voorbeeld van zo'n verandering ten opzichte van het materiaal dat we hebben behandeld, had de taal geen enumsvóór Java 5.
Standaardmethoden in interfaces - 1
Net zo verschilt Java 8 merkbaar van Java 7. Belangrijke vernieuwingen gaan we natuurlijk niet negeren. Aangezien we het in deze les over interfaces hebben, laten we eens kijken naar een update van de taal: standaardmethoden in interfaces . U weet al dat een interface geen gedrag implementeert . Het doel is om te beschrijven welk gedrag moet bestaan ​​in alle objecten die de interface implementeren . Maar ontwikkelaars kwamen regelmatig situaties tegen waarin de implementatie van een methode in alle klassen hetzelfde was. Laten we eens kijken naar ons voorbeeld van een oude auto:

public interface Car {

   public void gas();
  
   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class Truck implements Car {

   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}
Wat denk je dat het grootste probleem met deze code is? Je hebt waarschijnlijk gemerkt dat we een heleboel dubbele code hebben geschreven! Dit is een veelvoorkomend probleem bij het programmeren en moet worden vermeden. Het is een andere kwestie dat er geen specifieke oplossingen waren vóór de release van Java 8. Toen die versie uitkwam, werd het mogelijk om standaardmethoden te definiëren en deze rechtstreeks in een interface te implementeren! Hier is hoe het te doen:

public interface Car {

   public default void gas() {
       System.out.println("Gas!");
   }

   public default void brake() {
       System.out.println("Brake!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Nu zijn de methoden gas()en brake(), die voor alle auto's hetzelfde waren, naar de interface verplaatst, waardoor er geen dubbele code meer nodig is. En de methoden zijn beschikbaar in elk van de lessen!

public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
Wat als er 100 klassen zijn met een gas()methode, maar slechts 99 van hen zouden hetzelfde gedrag moeten vertonen? Verpest dat alles? Zal een standaardmethode in dit geval niet werken? Natuurlijk niet :) Standaard interfacemethoden kunnen worden overschreven.

public class UnusualCar implements Car {
   @Override
   public void go() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car slows down differently!");
   }
}
Alle andere 99 soorten auto's gebruiken de standaardmethode, terwijl deUnusualCarklasse is een uitzondering. Zonder het grote geheel te bederven, zal het rustig zijn eigen gedrag bepalen. Meerdere overerving in interfaces. Zoals u al weet, is er geen meervoudige overerving in Java. Daar zijn veel redenen voor. We zullen ze in detail bespreken in een aparte les. In andere talen, zoals C++, is de situatie omgekeerd. Geen enkele meervoudige overerving vormt een serieuze uitdaging, aangezien hetzelfde object verschillende kenmerken en gedragingen kan hebben. We zijn bijvoorbeeld kinderen voor onze ouders, studenten voor onze leraren en patiënten voor onze artsen. In het echte leven vervullen we verschillende rollen en gedragen we ons daarom anders: we gaan natuurlijk anders om met leraren dan met goede vrienden. Laten we proberen deze situatie in code te vertalen. Laten we ons voorstellen dat we twee klassen hebben: Vijver en Volière. Een vijver heeft zwemmende vogels nodig, een volière heeft vliegende vogels nodig. Om dit weer te geven, hebben we twee basisklassen gemaakt:FlyingBirden Waterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
Dienovereenkomstig zullen we vogels die erven FlyingBirdnaar de volière sturen, terwijl degenen die afkomstig zijn Waterfowlnaar de vijver gaan. Alles lijkt eenvoudig. Maar wat moeten we doen als we ergens een eend moeten definiëren? Eenden zwemmen en vliegen. Maar we hebben geen meervoudige erfenis. Gelukkig ondersteunt Java meerdere implementaties van interfaces. Als een klasse niet meerdere ouders kan erven, is het eenvoudig om meerdere interfaces te implementeren! Onze eend kan zowel een vliegende vogel als een zwemmende vogel zijn :) Om het gewenste resultaat te bereiken, hoeven we alleen maar interfaces te maken FlyingBirdin Waterfowlplaats van klassen.

public class Duck implements FlyingBird, Waterfowl {

   // Methods of both interfaces combine easily into one class
  
   @Override
   public void fly() {
       System.out.println("Flying!");
   }

   @Override
   public void swim() {

       System.out.println("Swimming!");
   }
}
Dit betekent dat ons programma de mogelijkheid behoudt om lessen flexibel te beheren. Wanneer we dat combineren met standaardmethoden, wordt ons vermogen om het gedrag van objecten te bepalen bijna onbegrensd! :)