Hver nye versjon av Java er forskjellig fra de forrige. Som et eksempel på en slik endring fra materialet vi har dekket, hadde ikke språket enumsfør Java 5.
Standardmetoder i grensesnitt - 1
Bare så er Java 8 merkbart forskjellig fra Java 7. Vi vil selvfølgelig ikke ignorere viktige innovasjoner. Siden vi snakker om grensesnitt i denne leksjonen, la oss vurdere en oppdatering av språket: standardmetoder i grensesnitt . Du vet allerede at et grensesnitt ikke implementerer atferd . Hensikten er å beskrive hvilken oppførsel som må eksistere i alle objekter som implementerer grensesnittet . Men utviklere møtte ofte situasjoner der implementeringen av en metode var den samme i alle klasser. La oss se på vårt 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!");
   }
}
Hva tror du er hovedproblemet med denne koden? Du har sikkert lagt merke til at vi skrev en haug med duplikatkode! Dette er et vanlig problem i programmering, og det bør unngås. Det er en annen sak at det ikke fantes noen spesielle løsninger før utgivelsen av Java 8. Da den versjonen kom ut, ble det mulig å definere standardmetoder og implementere dem rett inne i et grensesnitt! Slik gjør du det:
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 {

}
Nå er gas()og- brake()metodene, som var de samme for alle biler, flyttet inn i grensesnittet, noe som eliminerer behovet for duplikatkode. Og metodene er tilgjengelige i hver av klassene!
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();
   }
}
Hva om det er 100 klasser med en gas()metode, men bare 99 av dem skal ha samme oppførsel? Ødelegger det alt? Vil ikke en standardmetode fungere i dette tilfellet? Selvfølgelig ikke :) Standard grensesnittmetoder kan overstyres.
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 typene biler vil bruke standardmetoden, mensUnusualCarklasse er et unntak. Uten å ødelegge det store bildet, vil den rolig definere sin egen oppførsel. Multippel arv i grensesnitt. Som du allerede vet, er det ingen multippel arv i Java. Det er mange grunner til dette. Vi vil vurdere dem i detalj i en egen leksjon. På andre språk, for eksempel C++, er situasjonen omvendt. Ingen multippel arv utgjør en alvorlig utfordring, siden samme objekt kan ha flere forskjellige egenskaper og atferd. For eksempel er vi barn for foreldrene våre, studenter for lærerne våre og pasienter for legene våre. I det virkelige liv fyller vi forskjellige roller og oppfører oss følgelig annerledes: åpenbart samhandler vi med lærere annerledes enn med nære venner. La oss prøve å oversette denne situasjonen til kode. La oss forestille oss at vi har to klasser: Pond og Aviary. En dam trenger svømmende fugler, mens en voliere trenger flygende. For å representere dette opprettet vi to basisklasser:FlyingBirdog Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Følgelig vil vi sende fugler som arver FlyingBirdtil volieren, mens de som kommer fra Waterfowlvil gå til dammen. Alt virker greit. Men hva skal vi gjøre hvis vi trenger å definere en and et sted? Ender både svømmer og flyr. Men vi har ikke multippel arv. Heldigvis støtter Java flere implementeringer av grensesnitt. Hvis en klasse ikke kan arve flere foreldre, er det enkelt å implementere flere grensesnitt! Anda vår kan være en flygende fugl så vel som en svømmefugl :) For å oppnå ønsket resultat er alt vi trenger å gjøre å lage FlyingBirdog Waterfowlgrensesnitt i stedet 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!");
   }
}
Dette betyr at programmet vårt beholder muligheten til å administrere klasser fleksibelt. Når vi kombinerer det med standardmetoder, blir vår evne til å bestemme oppførselen til objekter nesten ubegrenset! :)