Setiap versi baru Java berbeda dari yang sebelumnya. Sebagai contoh perubahan dari materi yang telah kami bahas, bahasa tersebut tidak ada enumssebelum Java 5.
Metode default di antarmuka - 1
Jadi, Java 8 sangat berbeda dari Java 7. Kami tidak akan mengabaikan inovasi penting, tentunya. Karena kita berbicara tentang antarmuka dalam pelajaran ini, mari pertimbangkan satu pembaruan bahasa: metode default di antarmuka . Anda sudah tahu bahwa antarmuka tidak mengimplementasikan behavior . Tujuannya adalah untuk mendeskripsikan perilaku apa yang harus ada di semua objek yang mengimplementasikan antarmuka . Tetapi pengembang sering menghadapi situasi di mana penerapan metode sama di semua kelas. Mari kita lihat contoh mobil lama kita:
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!");
   }
}
Menurut Anda apa masalah utama dengan kode ini? Anda mungkin memperhatikan bahwa kami menulis banyak kode duplikat! Ini adalah masalah umum dalam pemrograman dan harus dihindari. Ini masalah lain bahwa tidak ada solusi khusus sebelum rilis Java 8. Ketika versi itu keluar, menjadi mungkin untuk menentukan metode default dan mengimplementasikannya langsung di dalam antarmuka! Inilah cara melakukannya:
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 {

}
Sekarang metode gas()and brake(), yang sama untuk semua mobil, telah dipindahkan ke antarmuka, menghilangkan kebutuhan akan kode duplikat. Dan metodenya tersedia di setiap kelas!
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();
   }
}
Bagaimana jika ada 100 kelas dengan gas()metode, tetapi hanya 99 kelas yang memiliki perilaku yang sama? Apakah itu merusak segalanya? Apakah metode default tidak berfungsi dalam kasus ini? Tentu saja tidak :) Metode antarmuka default dapat diganti.
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!");
   }
}
Semua 99 jenis mobil lainnya akan menggunakan metode default, sedangkanUnusualCarkelas adalah pengecualian. Tanpa merusak gambaran besarnya, ia akan dengan tenang menentukan perilakunya sendiri. Warisan berganda dalam antarmuka. Seperti yang sudah Anda ketahui, tidak ada pewarisan berganda di Jawa. Ada banyak alasan untuk ini. Kami akan mempertimbangkannya secara rinci dalam pelajaran terpisah. Dalam bahasa lain, seperti C++, situasinya terbalik. Tidak ada pewarisan berganda yang menghadirkan tantangan serius, karena objek yang sama dapat memiliki beberapa karakteristik dan perilaku yang berbeda. Misalnya, kita adalah anak bagi orang tua kita, murid bagi guru kita, dan pasien bagi dokter kita. Dalam kehidupan nyata, kami mengisi berbagai peran dan, karenanya, berperilaku berbeda: jelas kami berinteraksi dengan guru secara berbeda dibandingkan dengan teman dekat. Mari kita coba menerjemahkan situasi ini ke dalam kode. Bayangkan kita memiliki dua kelas: Pond dan Aviary. Kolam membutuhkan burung yang bisa berenang, sedangkan kandang burung membutuhkan burung yang bisa terbang. Untuk mewakili ini, kami membuat dua kelas dasar:FlyingBirddan Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Oleh karena itu, kami akan mengirimkan burung yang mewarisi FlyingBirdke kandang burung, sedangkan yang berasal dari Waterfowlakan pergi ke kolam. Segalanya tampak mudah. Tapi apa yang harus kita lakukan jika kita perlu mendefinisikan bebek di suatu tempat? Bebek berenang dan terbang. Tetapi kami tidak memiliki warisan berganda. Untungnya, Java mendukung banyak implementasi antarmuka. Jika suatu kelas tidak dapat mewarisi banyak orang tua, mengimplementasikan banyak antarmuka itu mudah! Bebek kita bisa menjadi burung terbang sekaligus burung perenang :) Untuk mencapai hasil yang diinginkan, yang perlu kita lakukan hanyalah membuat FlyingBirddan Waterfowlantarmuka daripada kelas.
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!");
   }
}
Ini berarti bahwa program kami mempertahankan kemampuan untuk mengelola kelas secara fleksibel. Saat kami menggabungkannya dengan metode default, kemampuan kami untuk menentukan perilaku objek menjadi hampir tidak terbatas! :)