Mengapa tidak ada pewarisan berganda di Java, tetapi menerapkan beberapa antarmuka diizinkan?


153

Java tidak mengizinkan banyak pewarisan, tetapi memungkinkan implementasi beberapa antarmuka. Mengapa?


1
Saya mengedit judul pertanyaan agar lebih deskriptif.
Bozho

4
Menariknya, dalam JDK 8, akan ada metode ekstensi yang akan memungkinkan definisi implementasi metode antarmuka. Aturan didefinisikan untuk mengatur berbagai perilaku warisan, tetapi bukan negara (yang saya pahami lebih bermasalah .
Edwin Dalorzo

1
Sebelum kalian membuang-buang waktu untuk jawaban yang hanya memberi tahu Anda "Bagaimana java mencapai beberapa warisan" ... Saya sarankan Anda untuk turun ke @Prabal Srivastava jawaban yang secara logis memberi Anda apa yang harus terjadi secara internal, untuk tidak membiarkan kelas seperti ini .. dan hanya mengizinkan antarmuka hak untuk mengizinkan pewarisan berganda.
Aplikasi Yo

Jawaban:


228

Karena antarmuka hanya menentukan apa yang dikerjakan kelas, bukan bagaimana melakukannya.

Masalah dengan multiple inheritance adalah bahwa dua kelas dapat mendefinisikan cara berbeda untuk melakukan hal yang sama, dan subclass tidak dapat memilih mana yang akan dipilih.


8
Saya biasa melakukan C ++ dan mengalami masalah yang sama persis beberapa kali. Saya baru-baru ini membaca tentang Scala memiliki "sifat" yang bagi saya tampak seperti sesuatu di antara cara "C ++" dan cara "Jawa" dalam melakukan sesuatu.
Niels Basjes

2
Dengan cara ini, Anda menghindari "masalah intan": en.wikipedia.org/wiki/Diamond_problem#The_diamond_problem
Nick L.

6
Karena Java 8 Anda dapat menentukan dua metode default yang identik, satu di setiap antarmuka. Jika Anda akan mengimplementasikan kedua antarmuka di kelas Anda, Anda harus mengganti metode ini di kelas itu sendiri, lihat: docs.oracle.com/javase/tutorial/java/IandI/…
bobbel

6
Jawaban ini tidak akurat. Masalahnya tidak menentukan bagaimana dan Java 8 ada untuk membuktikan. Di Java 8, dua antarmuka super dapat mendeklarasikan metode yang sama dengan implementasi yang berbeda, tapi itu bukan masalah karena metode antarmuka adalah virtual , jadi Anda bisa menimpa mereka dan masalahnya terpecahkan. Masalah sebenarnya adalah tentang ambiguitas dalam atribut , karena Anda tidak dapat menyelesaikan ambiguitas ini menimpa atribut (atribut tidak virtual).
Alex Oliveira

1
Apa yang Anda maksud dengan "atribut"?
Bozho

96

Salah satu instruktur perguruan tinggi saya menjelaskan kepada saya seperti ini:

Misalkan saya memiliki satu kelas, yaitu pemanggang roti, dan kelas lain, yaitu NuclearBomb. Mereka berdua mungkin memiliki pengaturan "kegelapan". Keduanya memiliki metode on (). (Satu memiliki off (), yang lain tidak.) Jika saya ingin membuat kelas yang merupakan subkelas dari kedua ... seperti yang Anda lihat, ini adalah masalah yang benar-benar bisa meledak di wajah saya di sini .

Jadi salah satu masalah utama adalah jika Anda memiliki dua kelas induk, mereka mungkin memiliki implementasi yang berbeda dari fitur yang sama - atau mungkin dua fitur berbeda dengan nama yang sama, seperti dalam contoh instruktur saya. Maka Anda harus berurusan dengan memutuskan mana subclass Anda akan digunakan. Ada beberapa cara untuk menangani hal ini, tentu saja - C ++ melakukannya - tetapi para perancang Jawa merasa bahwa ini akan membuat segalanya menjadi terlalu rumit.

Dengan antarmuka, Anda menggambarkan sesuatu yang mampu dilakukan oleh kelas, daripada meminjam metode kelas lain untuk melakukan sesuatu. Beberapa antarmuka jauh lebih kecil kemungkinannya menyebabkan konflik rumit yang perlu diselesaikan daripada beberapa kelas induk.


5
Terima kasih, NomeN. Sumber kutipan itu adalah seorang mahasiswa PhD bernama Brendan Burns, yang pada waktu itu juga adalah pengelola repositori sumber-sumber Quake 2 yang open-source. Sosok pergi.
Sintaksis

4
Masalah dengan analogi ini adalah bahwa jika Anda membuat subkelas bom nuklir dan pemanggang roti, "pemanggang nuklir" akan cukup meledak ketika digunakan.
101100

20
Jika seseorang memutuskan untuk mencampur bom nuklir dan pemanggang roti, ia layak bahwa bom meledak di wajahnya. Kutipan itu adalah alasan yang keliru
masoud

1
Bahasa pemrograman yang sama memungkinkan pewarisan berganda "antarmuka", jadi "pembenaran" ini tidak berlaku.
curiousguy

24

Karena warisan terlalu sering digunakan bahkan ketika Anda tidak bisa mengatakan "hei, metode itu terlihat berguna, saya akan memperpanjang kelas itu juga".

public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter, 
             AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...

Bisakah Anda menjelaskan mengapa Anda mengatakan warisan terlalu sering digunakan? Menciptakan kelas dewa adalah apa yang ingin saya lakukan! Saya menemukan begitu banyak orang yang bekerja di sekitar warisan tunggal dengan membuat kelas "Alat" yang memiliki metode statis.
Duncan Calvert

9
@DuncanCalvert: Tidak, Anda tidak ingin melakukan itu, tidak jika kode itu perlu pemeliharaan. Banyak metode statis melewatkan poin OO, tetapi pewarisan berganda berlebihan jauh lebih buruk karena Anda benar-benar kehilangan jejak kode mana yang digunakan di mana, serta apa kelas secara konseptual. Keduanya berusaha memecahkan masalah "bagaimana saya bisa menggunakan kode ini di tempat saya membutuhkannya", tetapi itu adalah masalah jangka pendek yang sederhana. Masalah jangka panjang yang jauh lebih sulit dipecahkan oleh desain OO yang tepat adalah "bagaimana cara mengubah kode ini tanpa membuat program rusak di 20 tempat berbeda dengan cara yang tidak terduga?
Michael Borgwardt

2
@DuncanCalvert: dan Anda menyelesaikannya dengan memiliki kelas dengan kohesi tinggi dan kopling rendah, yang berarti mereka berisi potongan data dan kode yang berinteraksi secara intensif satu sama lain, tetapi berinteraksi dengan sisa program hanya melalui API publik kecil dan sederhana. Maka Anda dapat memikirkan mereka dalam hal API itu alih-alih detail internal, yang penting karena orang hanya dapat menyimpan sejumlah detail dalam pikiran secara bersamaan.
Michael Borgwardt

18

Jawaban dari pertanyaan ini terletak pada kerja internal kompiler java (konstruktor chaining). Jika kita melihat kerja internal kompiler java:

public class Bank {
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank{
 public void printBankBalance(){
    System.out.println("20k");
  }
}

Setelah mengkompilasi ini terlihat seperti:

public class Bank {
  public Bank(){
   super();
  }
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank {
 SBI(){
   super();
 }
 public void printBankBalance(){
    System.out.println("20k");
  }
}

ketika kita memperluas kelas dan membuat objeknya, satu rantai konstruktor akan berjalan hingga Objectkelas.

Kode di atas akan berjalan dengan baik. tetapi jika kita memiliki kelas lain yang disebut Carmemanjang Bankdan satu kelas hybrid (multiple inheritance) disebut SBICar:

class Car extends Bank {
  Car() {
    super();
  }
  public void run(){
    System.out.println("99Km/h");
  }
}
class SBICar extends Bank, Car {
  SBICar() {
    super(); //NOTE: compile time ambiguity.
  }
  public void run() {
    System.out.println("99Km/h");
  }
  public void printBankBalance(){
    System.out.println("20k");
  }
}

Dalam hal ini (SBICar) akan gagal membuat rantai konstruktor ( kompilasi ambiguitas waktu ).

Untuk antarmuka ini diizinkan karena kami tidak dapat membuat objek darinya.

Untuk konsep defaultdan staticmetode baru silakan merujuk default di antarmuka .

Semoga ini akan menyelesaikan pertanyaan Anda. Terima kasih.


7

Menerapkan banyak antarmuka sangat berguna dan tidak menyebabkan banyak masalah bagi pelaksana bahasa maupun programmer. Jadi itu diizinkan. Berbagai warisan sementara juga bermanfaat, dapat menyebabkan masalah serius bagi pengguna ( berlian kematian yang ditakuti ). Dan sebagian besar hal yang Anda lakukan dengan pewarisan berganda juga dapat dilakukan dengan komposisi atau menggunakan kelas batin. Jadi multiple inheritance dilarang membawa lebih banyak masalah daripada keuntungan.


Apa masalah dengan "berlian maut"?
curiousguy

2
@curiousguy Berisi lebih dari satu sub-objek dari kelas dasar yang sama, ambiguitas (menggantikan dari yang digunakan kelas dasar), aturan rumit untuk menyelesaikan ambiguitas tersebut.
Tadeusz Kopec

@curiousguy: Jika suatu kerangka kerja menyediakan bahwa casting referensi objek ke referensi tipe dasar akan mempertahankan identitas, maka setiap instance objek harus memiliki tepat satu implementasi dari metode kelas dasar. Jika ToyotaCardan HybridCarkeduanya berasal dari Cardan mengesampingkan Car.Drive, dan jika PriusCarmewarisi keduanya tetapi tidak mengesampingkanDrive , sistem tidak akan memiliki cara untuk mengidentifikasi apa yang Car.Driveharus dilakukan virtual . Antarmuka menghindari masalah ini dengan menghindari kondisi miring di atas.
supercat

1
@supercat "sistem tidak memiliki cara untuk mengidentifikasi apa yang seharusnya dilakukan Car.Drive virtual." <- Atau bisa saja memberikan kesalahan kompilasi dan membuat Anda memilih satu secara eksplisit, seperti yang dilakukan C ++.
Chris Middleton

1
@ChrisMiddleton: Suatu metode void UseCar(Car &foo); tidak dapat diharapkan untuk memasukkan disambiguasi antara ToyotaCar::Drivedan HybridCar::Drive(karena seharusnya sering tidak mengetahui atau peduli bahwa jenis-jenis lain bahkan ada ) Suatu bahasa dapat, seperti halnya C ++, memerlukan kode yang ToyotaCar &myCaringin meneruskannya UseCarterlebih dahulu harus dilemparkan ke salah satu HybridCaratau ToyotaCar, tetapi karena ((Mobil) (HybridCar) myCar) .Drive` dan ((Car)(ToyotaCar)myCar).Drive akan melakukan hal yang berbeda, yang akan menyiratkan bahwa upcasts tidak melestarikan identitas.
supercat

6

Anda dapat menemukan jawaban yang akurat untuk kueri ini di halaman dokumentasi oracle tentang multiple inheritance

  1. Multiple inheritance of state: Kemampuan untuk mewarisi bidang dari beberapa kelas

    Salah satu alasan mengapa bahasa pemrograman Java tidak memungkinkan Anda untuk memperluas lebih dari satu kelas adalah untuk menghindari masalah multiple inheritance of state, yang merupakan kemampuan untuk mewarisi bidang dari beberapa kelas

    Jika beberapa pewarisan diizinkan dan Saat Anda membuat objek dengan membuat instance kelas itu, objek itu akan mewarisi bidang dari semua superclasses kelas. Itu akan menyebabkan dua masalah.

    1. Bagaimana jika metode atau konstruktor dari kelas super yang berbeda instantiate bidang yang sama?
    2. Metode atau konstruktor mana yang akan diutamakan?
  2. Berbagai warisan implementasi: Kemampuan untuk mewarisi definisi metode dari beberapa kelas

    Masalah dengan pendekatan ini: konflik nama dan ambiguitas . Jika subkelas dan superclass berisi nama metode (dan tanda tangan) yang sama, kompiler tidak dapat menentukan versi yang akan dipanggil.

    Tetapi java mendukung tipe multiple inheritance ini dengan metode default , yang telah diperkenalkan sejak rilis Java 8. Kompiler Java menyediakan beberapa aturan untuk menentukan metode default mana yang digunakan kelas tertentu.

    Lihat posting SE di bawah ini untuk detail lebih lanjut tentang menyelesaikan masalah berlian:

    Apa perbedaan antara kelas abstrak dan antarmuka di Java 8?

  3. Multiple inheritance of type: Kemampuan suatu kelas untuk mengimplementasikan lebih dari satu antarmuka.

    Karena antarmuka tidak mengandung bidang yang dapat diubah, Anda tidak perlu khawatir tentang masalah yang timbul dari banyak pewarisan status di sini.



4

Java mendukung banyak pewarisan melalui antarmuka saja. Kelas dapat mengimplementasikan sejumlah antarmuka tetapi hanya dapat memperluas satu kelas.

Warisan berganda tidak didukung karena menyebabkan masalah berlian yang mematikan. Namun, ini dapat diselesaikan tetapi mengarah ke sistem yang kompleks sehingga banyak warisan telah dijatuhkan oleh para pendiri Java.

Dalam sebuah buku putih berjudul “Java: an Overview” oleh James Gosling pada Februari 1995 ( tautan ) memberikan gambaran mengapa banyak warisan tidak didukung di Jawa.

Menurut Gosling:

"JAVA menghilangkan banyak fitur C ++ yang jarang digunakan, kurang dipahami, membingungkan, yang dalam pengalaman kami membawa lebih banyak kesedihan daripada manfaat. Ini terutama terdiri dari kelebihan operator (meskipun memiliki kelebihan metode), banyak pewarisan, dan pemaksaan otomatis yang ekstensif."


tautannya tidak dapat diakses. Silakan periksa dan perbarui.
MashukKhan

3

Untuk alasan yang sama C # tidak memungkinkan pewarisan berganda tetapi memungkinkan Anda untuk mengimplementasikan beberapa antarmuka.

Pelajaran yang dapat dipetik dari C ++ w / multiple inheritence adalah bahwa hal itu menyebabkan lebih banyak masalah daripada nilainya.

Antarmuka adalah kontrak hal-hal yang harus diimplementasikan oleh kelas Anda. Anda tidak mendapatkan fungsionalitas apa pun dari antarmuka. Inheritence memungkinkan Anda untuk mewarisi fungsi kelas induk (dan dalam multiple-inheritence, itu bisa sangat membingungkan).

Mengizinkan banyak antarmuka memungkinkan Anda untuk menggunakan Pola Desain (seperti Adaptor) untuk memecahkan jenis masalah yang sama yang dapat Anda pecahkan dengan menggunakan pewarisan berganda, tetapi dengan cara yang jauh lebih andal dan dapat diprediksi.


10
C # tidak memiliki banyak pewarisan justru karena Java tidak mengizinkannya. Itu dirancang jauh lebih lambat dari Jawa. Masalah utama dengan multiple inheritance yang saya pikir adalah cara orang diajarkan untuk menggunakannya kiri dan kanan. Konsep bahwa pendelegasian dalam kebanyakan kasus merupakan alternatif yang jauh lebih baik tidak ada di awal dan pertengahan tahun sembilan puluhan. Karena itu saya ingat contoh, di buku pelajaran, ketika Mobil adalah Roda dan Pintu dan Kaca Depan, vs. Mobil berisi Roda, Pintu, dan Kaca Depan. Jadi warisan tunggal di Jawa adalah reaksi spontan terhadap realitas itu.
Alexander Pogrebnyak

2
@AlexanderPogrebnyak: Pilih dua dari tiga berikut ini: (1) Izinkan pemeran identitas dari referensi subtipe ke referensi supertype; (2) Izinkan kelas menambahkan anggota publik virtual tanpa mengkompilasi ulang kelas turunan; (3) Memungkinkan kelas untuk secara implisit mewarisi anggota virtual dari beberapa kelas dasar tanpa harus secara eksplisit menentukannya. Saya tidak percaya ada kemungkinan untuk bahasa apa pun untuk mengelola ketiga hal di atas. Java memilih # 1 dan # 2, dan C # mengikutinya. Saya percaya C ++ hanya mengadopsi # 3. Secara pribadi, saya pikir # 1 dan # 2 lebih berguna daripada # 3, tetapi yang lain mungkin berbeda.
supercat

@supercat "Saya tidak percaya itu mungkin untuk bahasa apa pun untuk mengelola ketiga hal di atas" - jika offset anggota data ditentukan saat runtime, daripada waktu kompilasi (karena mereka berada di Objective-C's "ABI yang tidak rapuh" "), dan atau basis per-kelas (yaitu setiap kelas konkret memiliki tabel offset anggota sendiri), maka saya pikir ketiga tujuan dapat dicapai.
The Paramagnetic Croissant

@TheParamagneticCroissant: Masalah semantik utama adalah # 1. Jika D1dan D2keduanya mewarisi dari B, dan masing-masing menimpa fungsi f, dan jika objadalah sebuah instance dari tipe Syang mewarisi dari keduanya D1dan D2tetapi tidak menimpa f, maka casting referensi Ske D1harus menghasilkan sesuatu yang fmenggunakan D1override, dan casting untuk Btidak boleh ganti itu. Demikian juga pengecoran referensi Suntuk D2harus menghasilkan sesuatu yang fmenggunakan yang D2menimpa, dan casting untuk Btidak harus mengubah itu. Jika suatu bahasa tidak perlu memperbolehkan anggota virtual untuk ditambahkan ...
supercat

1
@TheParamagneticCroissant: Itu bisa, dan daftar pilihan saya agak terlalu disederhanakan agar sesuai dengan komentar, tetapi menunda waktu tayang membuat penulis D1, D2, atau S tidak mungkin tahu perubahan apa yang dapat mereka lakukan tanpa melanggar konsumen kelas mereka.
supercat

2

Karena topik ini tidak dekat, saya akan memposting jawaban ini, saya harap ini membantu seseorang untuk memahami mengapa java tidak memungkinkan banyak pewarisan.

Pertimbangkan kelas berikut:

public class Abc{

    public void doSomething(){

    }

}

Dalam hal ini kelas Abc tidak memperluas apa-apa, bukan? Tidak begitu cepat, kelas ini secara implisit memperluas Object kelas, kelas dasar yang memungkinkan semuanya berfungsi di java. Semuanya adalah objek.

Jika Anda mencoba untuk menggunakan kelas atas Anda akan melihat bahwa IDE Anda memungkinkan Anda untuk menggunakan metode seperti: equals(Object o), toString(), dll, tetapi Anda tidak menyatakan metode tersebut, mereka datang dari kelas dasarObject

Kamu bisa mencoba:

public class Abc extends String{

    public void doSomething(){

    }

}

Ini baik-baik saja, karena kelas Anda tidak akan implisit meluas Objecttetapi akan meluas Stringkarena Anda mengatakannya. Pertimbangkan perubahan berikut:

public class Abc{

    public void doSomething(){

    }

    @Override
    public String toString(){
        return "hello";
    }

}

Sekarang kelas Anda akan selalu mengembalikan "halo" jika Anda memanggil toString ().

Sekarang bayangkan kelas berikut:

public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}

Sekali lagi kelas Flyerimplisit extends Object yang memiliki metode toString(), setiap kelas akan memiliki metode ini karena mereka semua diperluas Objectsecara tidak langsung, jadi, jika Anda menelepon toString()dari Bird, toString()java mana yang harus digunakan? Dari Abcatau Flyer? Ini akan terjadi dengan setiap kelas yang mencoba memperluas dua atau lebih kelas, untuk menghindari "metode tabrakan" semacam ini mereka membangun ide antarmuka , pada dasarnya Anda bisa menganggapnya sebagai kelas abstrak yang tidak memperluas Obyek secara tidak langsung . Karena mereka abstrak, mereka harus diimplementasikan oleh sebuah kelas, yang merupakan objek(Anda tidak dapat membuat antarmuka saja, mereka harus diimplementasikan oleh sebuah kelas), sehingga semuanya akan terus berfungsi dengan baik.

Untuk membedakan kelas dari antarmuka, penerapan kata kunci hanya diperuntukkan bagi antarmuka.

Anda bisa mengimplementasikan antarmuka apa pun yang Anda suka di kelas yang sama karena mereka tidak memperluas apa pun secara default (tapi Anda bisa membuat antarmuka yang memperluas antarmuka lain, tetapi sekali lagi, antarmuka "ayah" tidak akan memperluas Obyek "), sehingga antarmuka adalah hanya sebuah antarmuka dan mereka tidak akan menderita dari " metode tanda tangan colissions ", jika mereka melakukan compiler akan memberikan peringatan kepada Anda dan Anda hanya perlu mengubah metode tanda tangan untuk memperbaikinya (signature = nama metode + params + jenis kembali) .

public interface Flyer{

    public void makeFly(); // <- method without implementation

}

public class Bird extends Abc implements Flyer{

    public void doAnotherThing(){

    }

    @Override
    public void makeFly(){ // <- implementation of Flyer interface

    }

    // Flyer does not have toString() method or any method from class Object, 
    // no method signature collision will happen here

}

1

Karena sebuah antarmuka hanyalah kontrak. Dan kelas sebenarnya adalah wadah untuk data.


Kesulitan mendasar dengan multiple inheritance adalah kemungkinan bahwa sebuah kelas dapat mewarisi anggota melalui beberapa jalur yang mengimplementasikannya secara berbeda, tanpa menyediakan implementasi utamanya sendiri. Warisan antarmuka menghindari hal ini karena satu-satunya tempat anggota antarmuka dapat diimplementasikan adalah di kelas, yang turunannya akan terbatas pada pewarisan tunggal.
supercat

1

Misalnya dua kelas A, B memiliki metode yang sama m1 (). Dan kelas C memperpanjang A, B.

 class C extends A, B // for explaining purpose.

Sekarang, kelas C akan mencari definisi m1. Pertama, ia akan mencari di kelas jika tidak menemukan maka akan memeriksa ke kelas orang tua. Kedua A, B memiliki definisi Jadi di sini terjadi ambiguitas definisi mana yang harus dipilih. Jadi JAWA TIDAK MENDUKUNG WARISAN GANDA.


bagaimana dengan membuat kompiler java memberikan kompiler jika metode atau variabel yang sama didefinisikan di kedua kelas induk sehingga kita dapat mengubah kode ...
siluveru kiran kumar

1

Java tidak mendukung multiple inheritance karena dua alasan:

  1. Di java, setiap kelas adalah anak dari Objectkelas. Ketika mewarisi dari lebih dari satu kelas super, sub kelas mendapatkan ambiguitas untuk mendapatkan properti dari kelas Obyek.
  2. Dalam java setiap kelas memiliki konstruktor, apakah kita menulisnya secara eksplisit atau tidak sama sekali. Pernyataan pertama adalah panggilan super()untuk memanggil konstruktor kelas perjamuan. Jika kelas memiliki lebih dari satu kelas super, itu jadi bingung.

Jadi, ketika satu kelas memanjang dari lebih dari satu kelas super, kami mendapatkan kesalahan waktu kompilasi.


0

Ambil contoh kasus di mana Kelas A memiliki metode getSomething dan kelas B memiliki metode getSomething dan kelas C meluas A dan B. Apa yang akan terjadi jika seseorang bernama C.getSomething? Tidak ada cara untuk menentukan metode mana yang harus dihubungi.

Antarmuka pada dasarnya hanya menentukan metode apa yang perlu dimiliki oleh kelas pelaksana. Kelas yang mengimplementasikan beberapa antarmuka hanya berarti kelas harus mengimplementasikan metode dari semua antarmuka itu. Whci tidak akan menyebabkan masalah apa pun seperti yang dijelaskan di atas.


2
" Apa yang akan terjadi jika seseorang memanggil C.getSomething. " Ini adalah kesalahan dalam C ++. Masalah terpecahkan.
curiousguy

Itulah intinya ... itu adalah contoh balasan yang saya pikir sudah jelas. Saya menunjukkan bahwa tidak ada cara untuk menentukan metode mendapatkan sesuatu yang harus dipanggil. Juga sebagai catatan, pertanyaan itu terkait dengan java tidak c ++
John Kane

Maaf saya tidak mengerti maksud Anda. Jelas, ada beberapa ambiguitas dalam beberapa kasus dengan MI. Bagaimana itu contohnya? Siapa yang mengklaim bahwa MI tidak pernah menghasilkan ambiguitas? " Juga sebagai catatan tambahan, pertanyaannya terkait dengan java, bukan c ++ " Jadi?
curiousguy

Saya hanya mencoba menunjukkan mengapa ambiguitas itu ada dan mengapa tidak dengan antarmuka.
John Kane

Ya, MI dapat menghasilkan panggilan ambigu. Jadi bisa overloading. Jadi Java harus menghapus overloading?
curiousguy

0

Pertimbangkan skenario di mana Test1, Test2 dan Test3 adalah tiga kelas. Kelas Test3 mewarisi kelas Test2 dan Test1. Jika kelas Test1 dan Test2 memiliki metode yang sama dan Anda memanggilnya dari objek kelas anak, akan ada ambiguitas untuk memanggil metode dari kelas Test1 atau Test2 tetapi tidak ada ambiguitas untuk antarmuka seperti di antarmuka tidak ada implementasi di sana.


0

Java tidak mendukung multiple inheritance, multipath dan hybrid inheritance karena masalah ambiguitas:

 Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass i.e., class C , so  C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ?  So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.

pewarisan berganda

Tautan Referensi: https://plus.google.com/u/0/communities/102217496457095083679


0

secara sederhana kita semua tahu, kita dapat mewarisi (memperluas) satu kelas tetapi kita dapat mengimplementasikan begitu banyak antarmuka .. itu karena dalam antarmuka kita tidak memberikan implementasi, katakan saja fungsionalitasnya. misalkan jika java dapat meluas begitu banyak kelas dan mereka memiliki metode yang sama .. pada titik ini jika kita mencoba memanggil metode super kelas di sub kelas metode apa yang seharusnya dijalankan ??, kompiler menjadi bingung contoh: - mencoba beberapa ekstensi tetapi dalam antarmuka metode-metode itu tidak memiliki tubuh kita harus mengimplementasikannya di sub kelas .. coba beberapa alat jadi jangan khawatir ..


1
Anda bisa memposting di sini contoh-contoh itu. Tanpa itu ini tampak seperti blok teks ke pertanyaan berusia 9 tahun yang dijawab ratusan kali.
Pochmurnik

-1

* Ini adalah jawaban sederhana karena saya seorang pemula di Jawa *

Anggap ada tiga kelas X, Ydan Z.

Jadi kita mewarisi seperti X extends Y, Z Dan keduanya Ydan Zmemiliki metode alphabet()dengan tipe pengembalian dan argumen yang sama. Metode ini alphabet()di Ymengatakan untuk menampilkan alfabet pertama dan alfabet metode di Zmengatakan menampilkan alfabet terakhir . Jadi inilah ambiguitas ketika alphabet()dipanggil oleh X. Apakah itu mengatakan untuk menampilkan alfabet pertama atau terakhir ??? Jadi java tidak mendukung multiple inheritance. Dalam hal Antarmuka, pertimbangkan Ydan . Jadi tidak ada alasan untuk meningkatkan ambiguitas. Kita dapat mendefinisikan metode dengan apa pun yang kita inginkan di dalam kelas .Z sebagai antarmuka. Jadi keduanya akan berisi deklarasi metode alphabet()tetapi bukan definisi. Itu tidak akan memberitahu apakah akan menampilkan alfabet pertama atau alfabet terakhir atau apa pun tetapi hanya akan mendeklarasikan metodealphabet()X

Jadi singkatnya, dalam definisi Interface dilakukan setelah implementasi sehingga tidak ada kebingungan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.