Fiecare versiune nouă de Java diferă de cele care au apărut înainte. Iată un exemplu de modificări ale materialelor pe care le-am acoperit: înainte de Java 5, limbajul nu avea
În mod similar, Java 8 diferă semnificativ de Java 7. Majoritatea lecțiilor noastre au fost scrise pentru a 7-a versiune a limbajului, dar bineînțeles că nu vom ignora inovațiile importante. Deoarece vorbim deja despre interfețe în această lecție, vom lua în considerare o actualizare - metodele implicite în interfețe . Știți deja că o interfață nu implementează comportamentul . Sarcina sa este de a descrie comportamentul pe care trebuie să-l aibă toate obiectele care îl implementează. Dar dezvoltatorii au întâlnit frecvent situații în care implementarea unei metode este aceeași în toate clasele. Să luăm în considerare exemplul nostru de mașină veche:
enum
s. ![Metode implicite în interfețe - 1](https://cdn.codegym.cc/images/article/34d25d0e-f8da-43f7-ab2b-5333c5a01585/800.jpeg)
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 gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
„După părerea dumneavoastră, care este principala problemă cu acest cod? Probabil ați observat că am scris o grămadă de coduri repetate! Această problemă este obișnuită în programare și trebuie să o evitați. Este o altă problemă că anumite soluții nu existau înainte. A fost lansat Java 8. Odată cu această versiune, a venit posibilitatea de a specifica metode implicite și de a le implementa chiar în interfață! Iată cum faci asta:
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 {
}
Acum metodele gas()
și brake()
, care erau aceleași pentru toate mașinile, au fost mutate în interfață. Nu este necesar niciun cod repetat. Mai mult, metodele sunt disponibile în fiecare clasă!
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();
}
}
Ce se întâmplă dacă există 100 de clase cu gas()
metoda, dar doar 99 dintre ele au același comportament? Asta distruge totul și face ca metoda implicită să nu fie potrivită pentru această situație? Desigur, nu :) Metodele implicite din interfețe pot fi suprascrise în același mod ca și cele obișnuite.
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car decelerates differently!");
}
}
Toate celelalte 99 de tipuri de mașini vor implementa metoda implicită șiUnusualCar
clasa, care este o excepție, nu va strica imaginea de ansamblu și își definește calm propriul comportament. Moștenirea multiplă a interfețelor. După cum știți deja, Java nu acceptă moștenirea multiplă. Există multe motive pentru aceasta. Le vom analiza în detaliu într-o lecție separată. Alte limbaje, cum ar fi C++, îl acceptă. Fără moștenire multiplă, apare o problemă serioasă: un obiect poate avea mai multe caracteristici și „comportamente” diferite. Iată un exemplu din viață: suntem copii pentru părinții noștri, studenți pentru profesorii noștri și pacienți pentru medicii noștri. În viață, ne asumăm roluri diferite și, în consecință, ne comportăm diferit: evident, nu am vorbi cu profesorii în același mod în care vorbim cu prietenii noștri apropiați. Să încercăm să traducem asta în cod. Imaginează-ți că avem două clase: Balta si Voliera. Pentru iaz avem nevoie de păsări de apă; pentru volieră, avem nevoie de păsări zburătoare. Pentru a face acest lucru, am creat două clase de bază:FlyingBird
și Waterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
În consecință, vom trimite păsări ale căror clase moștenesc FlyingBird
în volieră și vom trimite păsări care moștenesc Waterfowl
la iaz. Totul pare foarte simplu. Dar unde trimitem o rață? Înoată și zboară. Și nu avem moștenire multiplă. Din fericire, Java acceptă implementări multiple de interfețe. Deși o clasă nu poate moșteni mai mulți părinți, poate implementa cu ușurință mai multe interfețe! Rața noastră poate fi atât o pasăre zburătoare, cât și o pasăre de apă :) Trebuie pur și simplu să facem FlyingBird
și să facem Waterfowl
interfețe, mai degrabă decât clase pentru a obține rezultatul dorit.
public class Duck implements FlyingBird, Waterfowl {
// The methods of both interfaces can be easily combined into one class
@Override
public void fly() {
System.out.println("Fly!");
}
@Override
public void swim() {
System.out.println("Swim!");
}
}
În consecință, programul nostru păstrează flexibilitatea claselor și, în combinație cu metodele implicite, capacitatea noastră de a defini comportamentul obiectelor devine aproape nelimitată! :)