Hver ny version af Java adskiller sig fra de tidligere. Som et eksempel på en sådan ændring fra materiale, vi har dækket, havde sproget ikke enumsfør Java 5.
Standardmetoder i grænseflader - 1
Bare så, Java 8 er mærkbart anderledes end Java 7. Vi vil selvfølgelig ikke ignorere vigtige innovationer. Da vi taler om grænseflader i denne lektion, lad os overveje en opdatering til sproget: standardmetoder i grænseflader . Du ved allerede, at en grænseflade ikke implementerer adfærd . Dens formål er at beskrive, hvilken adfærd der skal eksistere i alle objekter, der implementerer grænsefladen . Men udviklere stødte ofte på situationer, hvor implementeringen af ​​en metode var den samme i alle klasser. Lad os se på vores gamle bileksempel:
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!");
   }
}
Hvad tror du, hovedproblemet med denne kode er? Du har sikkert lagt mærke til, at vi skrev en masse dubletkode! Dette er et almindeligt problem i programmering, og det bør undgås. Det er en anden sag, at der ikke var nogen særlige løsninger før udgivelsen af ​​Java 8. Da den version kom ud, blev det muligt at definere standardmetoder og implementere dem direkte i en grænseflade! Sådan gør du:
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 er gas()og- brake()metoderne, som var de samme for alle biler, blevet flyttet ind i grænsefladen, hvilket eliminerer behovet for duplikatkode. Og metoderne er tilgængelige i hver af klasserne!
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();
   }
}
Hvad hvis der er 100 klasser med en gas()metode, men kun 99 af dem skulle have samme adfærd? Forkæler det alt? Vil en standardmetode ikke fungere i dette tilfælde? Selvfølgelig ikke :) Standard interface metoder kan tilsidesættes.
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 de andre 99 typer biler vil anvende standardmetoden, mensUnusualCarklasse er en undtagelse. Uden at spolere det store billede, vil det roligt definere sin egen adfærd. Multipel arv i grænseflader. Som du allerede ved, er der ingen multipel arv i Java. Det er der mange grunde til. Vi vil overveje dem i detaljer i en separat lektion. På andre sprog, såsom C++, er situationen omvendt. Ingen multipel arv udgør en alvorlig udfordring, da det samme objekt kan have flere forskellige karakteristika og adfærd. For eksempel er vi børn for vores forældre, studerende for vores lærere og patienter for vores læger. I det virkelige liv udfylder vi forskellige roller og opfører os derfor anderledes: naturligvis interagerer vi med lærere anderledes end med nære venner. Lad os prøve at oversætte denne situation til kode. Lad os forestille os, at vi har to klasser: Dam og Voliere. En dam har brug for svømmefugle, mens en voliere har brug for flyvende. For at repræsentere dette oprettede vi to basisklasser:FlyingBirdog Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Derfor vil vi sende fugle, der arver, FlyingBirdtil volieren, mens de, der kommer fra, Waterfowlvil gå til dammen. Alt virker ligetil. Men hvad skal vi gøre, hvis vi skal definere en and et sted? Ænder både svømmer og flyver. Men vi har ikke multipel arv. Heldigvis understøtter Java flere implementeringer af grænseflader. Hvis en klasse ikke kan arve flere forældre, er det nemt at implementere flere grænseflader! Vores and kan være en flyvende fugl såvel som en svømmefugl :) For at opnå det ønskede resultat er alt, hvad vi skal gøre, at lave FlyingBirdog Waterfowlgrænseflader frem for klasser.
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!");
   }
}
Det betyder, at vores program bevarer muligheden for fleksibelt at administrere klasser. Når vi kombinerer det med standardmetoder, bliver vores evne til at bestemme objekters adfærd næsten ubegrænset! :)