Ang bawat bagong bersyon ng Java ay naiiba sa mga nauna. Bilang isang halimbawa ng naturang pagbabago mula sa materyal na aming nasaklaw, ang wika ay wala enumsbago ang Java 5.
Mga default na pamamaraan sa mga interface - 1
Kaya lang, ang Java 8 ay kapansin-pansing naiiba sa Java 7. Siyempre, hindi namin babalewalain ang mahahalagang inobasyon. Dahil pinag-uusapan natin ang tungkol sa mga interface sa araling ito, isaalang-alang natin ang isang update sa wika: mga default na pamamaraan sa mga interface . Alam mo na na ang isang interface ay hindi nagpapatupad ng pag-uugali . Ang layunin nito ay ilarawan kung anong pag-uugali ang dapat na umiiral sa lahat ng mga bagay na nagpapatupad ng interface . Ngunit ang mga developer ay madalas na nakatagpo ng mga sitwasyon kung saan ang pagpapatupad ng isang pamamaraan ay pareho sa lahat ng mga klase. Tingnan natin ang aming lumang halimbawa ng kotse:

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!");
   }
}
Ano sa palagay mo ang pangunahing problema sa code na ito? Marahil ay napansin mo na nagsulat kami ng isang grupo ng duplicate na code! Ito ay isang karaniwang problema sa programming at dapat itong iwasan. Ito ay isa pang bagay na walang mga partikular na solusyon bago ang paglabas ng Java 8. Nang lumabas ang bersyong iyon, naging posible na tukuyin ang mga default na pamamaraan at ipatupad ang mga ito sa loob mismo ng isang interface! Narito kung paano ito gawin:

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 {

}
Ngayon ang gas()at brake()mga pamamaraan, na pareho para sa lahat ng mga kotse, ay inilipat sa interface, na inaalis ang pangangailangan para sa duplicate na code. At ang mga pamamaraan ay magagamit sa bawat isa sa mga klase!

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();
   }
}
Paano kung mayroong 100 klase na may gas()pamamaraan, ngunit 99 lamang sa kanila ang dapat magkaroon ng parehong pag-uugali? Sinisira ba niyan ang lahat? Hindi ba gagana ang isang default na paraan sa kasong ito? Syempre hindi :) Maaaring ma-override ang mga default na paraan ng interface.

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!");
   }
}
Ang lahat ng iba pang 99 na uri ng mga kotse ay gagamitin ang default na paraan, habang angUnusualCarang klase ay isang pagbubukod. Nang hindi sinisira ang malaking larawan, kalmado nitong tutukuyin ang sarili nitong pag-uugali. Maramihang pamana sa mga interface. Tulad ng alam mo na, walang multiple inheritance sa Java. Maraming dahilan para dito. Isasaalang-alang namin ang mga ito nang detalyado sa isang hiwalay na aralin. Sa ibang mga wika, tulad ng C++, ang sitwasyon ay baligtad. Walang maraming inheritance na nagpapakita ng seryosong hamon, dahil ang parehong bagay ay maaaring magkaroon ng ilang magkakaibang katangian at pag-uugali. Halimbawa, tayo ay mga anak sa ating mga magulang, mga estudyante sa ating mga guro, at mga pasyente sa ating mga doktor. Sa totoong buhay, iba't ibang tungkulin ang ginagampanan natin at, nang naaayon, iba ang kilos natin: maliwanag na iba ang pakikisalamuha natin sa mga guro kaysa sa malalapit na kaibigan. Subukan nating isalin ang sitwasyong ito sa code. Isipin natin na mayroon tayong dalawang klase: Pond at Aviary. Ang isang pond ay nangangailangan ng mga ibong lumalangoy, habang ang isang aviary ay nangangailangan ng mga lumilipad. Upang kumatawan dito, lumikha kami ng dalawang baseng klase:FlyingBirdat Waterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
Alinsunod dito, magpapadala kami ng mga ibon na nagmamana FlyingBirdsa aviary, habang ang mga nagmula Waterfowlay pupunta sa lawa. Parang diretso ang lahat. Ngunit ano ang dapat nating gawin kung kailangan nating tukuyin ang isang pato sa isang lugar? Ang mga itik ay parehong lumalangoy at lumilipad. Pero wala kaming multiple inheritance. Sa kabutihang palad, sinusuportahan ng Java ang maraming pagpapatupad ng mga interface. Kung ang isang klase ay hindi maaaring magmana ng maraming magulang, ang pagpapatupad ng maraming interface ay madali! Ang aming pato ay maaaring maging isang lumilipad na ibong pati na rin isang ibong lumalangoy :) Upang makamit ang ninanais na resulta, ang kailangan lang nating gawin ay gumawa FlyingBirdat Waterfowlmag-interface kaysa sa mga klase.

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!");
   }
}
Nangangahulugan ito na ang aming programa ay nagpapanatili ng kakayahang flexible na pamahalaan ang mga klase. Kapag pinagsama namin iyon sa mga default na pamamaraan, ang aming kakayahang matukoy ang pag-uugali ng mga bagay ay nagiging halos walang limitasyon! :)