Anda tidak dapat memperpanjang dua kelas atau lebih sekaligus. Warisan berganda tidak diizinkan di java.
yogsma
Jawaban:
156
Anda hanya dapat Perpanjang satu kelas. Dan mengimplementasikan Antarmuka dari banyak sumber.
Memperluas beberapa kelas tidak tersedia. Satu-satunya solusi yang dapat saya pikirkan adalah tidak mewarisi kelas mana pun melainkan memiliki variabel internal masing-masing kelas dan melakukan lebih banyak proxy dengan mengarahkan permintaan ke objek Anda ke objek yang Anda inginkan.
publicclassCustomActivityextendsActivity{privateAnotherClass mClass;protectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
mClass =newAnotherClass(this);}//Implement each method you want to use.publicString getInfoFromOtherClass(){return mClass.getInfoFromOtherClass();}}
ini adalah solusi terbaik yang saya miliki. Anda bisa mendapatkan fungsionalitas dari kedua kelas dan Masih hanya benar-benar satu jenis kelas.
Kekurangannya adalah bahwa Anda tidak dapat masuk ke dalam Cetakan kelas Internal menggunakan gips.
Pendekatan intersting, apa pendapat para ahli tentang teknik ini? Saya ingin menggali lebih dalam.
TechNyquist
1
Apakah boleh dengan konvensi?
mulai
2
Tidak dapat membuat kelas dalam bekerja di a Fragment. Aktivitas saya harus diperluas Fragment, yang berarti saya benar-benar perlu getView(), yang tidak akan berfungsi jika itu di dalam kelas batin, dan kode di sana adalah tempat saya perlu menggunakan kode ListActivity, jadi saya tidak dapat memperluas dua kali, ATAU melakukan kelas dalam dalam contoh ini.
Azurespot
Ini adalah solusi terbaik untuk memperluas kelas abstrak di mana Anda memerlukan akses ke variabel dari kelas yang diterapkan.
tak3shi
45
Seperti yang dikatakan semua orang. Tidak bisa. Namun, meskipun orang telah mengatakan berkali-kali selama bertahun-tahun bahwa Anda harus menggunakan banyak antarmuka, mereka belum benar-benar memahami caranya. Semoga ini bisa membantu.
Katakanlah Anda memiliki class Foodan class Barbahwa Anda berdua ingin mencoba memperluas menjadi a class FooBar. Tentu saja, seperti yang Anda katakan, Anda tidak dapat melakukan:
publicclassFooBarextendsFoo,Bar
Orang sudah masuk ke alasan untuk ini sampai batas tertentu sudah. Sebagai gantinya, tulis interfacesuntuk keduanya Foodan Barmencakup semua metode publik mereka. Misalnya
Sekarang, dengan class FooBar, Anda dapat menerapkan kedua FooInterfacedan BarInterfacesekaligus menjaga Foodan Barobjek dan hanya lewat metode langsung melalui:
publicclassFooBarimplementsFooInterface,BarInterface{Foo myFoo;Bar myBar;// You can have the FooBar constructor require the arguments for both// the Foo and the Bar constructorspublicFooBar(int x,int y,int z){
myFoo =newFoo(x);
myBar =newBar(y, z);}// Or have the Foo and Bar objects passed right inpublicFooBar(Foo newFoo,Bar newBar){
myFoo = newFoo;
myBar = newBar;}publicvoid methodA(){
myFoo.methodA();}publicint methodB(){return myFoo.methodB();}publicint methodC(int i){return myBar.methodC(i);}//...}
Bonus untuk metode ini, adalah bahwa FooBarobjek cocok dengan cetakan keduanya FooInterfacedan BarInterface. Itu berarti ini baik-baik saja:
Ini adalah jawaban yang sangat bagus, namun saya melihat beberapa masalah dengannya yang perlu ditangani secara lebih rinci. Pertama memanjang dari dua kelas yang ada akan sedikit lebih bermasalah dan akan ada sejumlah rintangan tambahan untuk dilalui, Kedua adalah jika antarmuka Foo dan Bar keduanya memiliki fungsi yang sama, Anda harus memiliki urutan prioritas. Memperluas kelas Anda secara eksplisit akan memaksa Anda untuk mengambil keputusan di depan. Tetap saja, Pilihan luar biasa :) +1
The Lazy Coder
Bagaimana jika kita harus membuat kelas baru "sering" dan membuat masing-masing kelas mengimplementasikan kedua antarmuka? Kemudian, kita harus mengulangi implementasi boilerplate ini di setiap kelas. Apakah ada cara yang lebih baik untuk membuat kelas "menerapkan" dua set perilaku?
MasterJoe2
1
@ MasterJoe2 Sejujurnya, saya belum banyak menggunakan Java untuk sementara waktu sekarang (saya berhenti ketika saya menulis jawaban ini). Salah satu alasan saya menghindarinya sekarang adalah masalah yang Anda ajukan. Firasat untuk arah yang mungkin bisa Anda selidiki, adalah menulis kelas abstrak yang mengimplementasikan kedua antarmuka, dan memperluasnya. Namun saya tidak tahu apakah itu Java yang valid, dan saya merasa bahwa Anda hanya akan berakhir dengan masalah asli yang sama ketika Anda ingin membuat perubahan pada kelas implementasi di masa depan. Maaf saya tidak bisa membantu.
SCB
37
Anda ingin menggunakan antarmuka. Secara umum, multiple inheritance buruk karena Masalah Berlian:
abstractclass A {abstract string foo();}class B extends A {
string foo (){return"bar";}}class C extends A {
string foo(){return"baz";}}class D extends B, C {
string foo(){returnsuper.foo();}//What do I do? Which method should I call?}
C ++ dan lainnya punya beberapa cara untuk menyelesaikan ini, mis
Saya tidak pernah mengerti mengapa masalah berlian sebenarnya adalah masalah yang mencegah pewarisan berganda. Mengapa kompilator tidak bisa mengeluh hanya jika ada metode yang bertentangan dengan nama yang sama?
pete
1
Untuk kompiler yang cukup cerdas, tidak. Memecahkannya di tingkat kompilator adalah mungkin, dan memang C ++ melakukannya dengan virtual class. Melakukannya datang dengan banyak peringatan dan peringatan, baik untuk kompiler dan pengembang.
David Souther
1
Bagaimana dengan metode standar yang sama di dua antarmuka? Itu adalah contoh lain dari masalah berlian, yang dapat ditangani java.
Anda tidak dapat kembali "bar"atau "baz"dengan tipe metode void. Bagaimanapun, penjelasan yang baik xD
xdevs23
22
Ya, seperti yang ditulis semua orang, Anda tidak dapat melakukan banyak pewarisan di Jawa. Jika Anda memiliki dua kelas dari mana Anda ingin menggunakan kode, Anda biasanya hanya subkelas satu (katakanlah kelas A). Untuk kelas B, Anda abstrak metode penting itu ke antarmuka BInterface(nama jelek, tetapi Anda mendapatkan ide), lalu katakan Main extends A implements BInterface. Di dalam, Anda dapat membuat instance objek kelas Bdan menerapkan semua metode BInterfacedengan memanggil fungsi yang sesuaiB .
Ini mengubah hubungan "is-a" menjadi hubungan "has-a" seperti Mainsekarang A, tetapi memilikiB . Tergantung pada kasus penggunaan Anda, Anda bahkan dapat membuat perubahan itu secara eksplisit dengan menghapus BInterfacedari Akelas Anda dan sebagai gantinya memberikan metode untuk mengakses objek B Anda secara langsung.
aww mengapa downvote? Saya tidak bersikap jahat, saya hanya berpikir dia mampu melakukan beberapa bacaan dan memikirkan masalah sendiri terlebih dahulu sebelum kami membangun kelasnya untuknya
slandau
6
Java tidak mendukung multiple inheritance, tetapi Anda dapat mencoba mengimplementasikan dua atau lebih antarmuka.
Seperti alternatif lain, mungkin Anda dapat menggunakan antarmuka dengan implementasi metode standar. Itu tentu saja tergantung dari apa yang ingin Anda lakukan.
Misalnya, Anda bisa membuat kelas abstrak dan antarmuka:
publicabstractclassFatherClass{abstractvoid methodInherit(){//... do something}}publicinterfaceInterfaceWithDefaultsMethods{defaultvoid anotherMethod(){//... do something//... maybe a method with a callable for call another function.}}
Jadi, setelah itu, Anda bisa memperluas dan mengimplementasikan kedua kelas dan menggunakan kedua metode.
Parallaxordan ParallaxControllertidak diketahui, jadi saya berasumsi mereka bukan kelas-SDK. Jadi ini tidak berfungsi untuk saya (dan dengan demikian jawaban ini menunjukkan kesalahan). Apa itu ParallaxController? Apakah ini ketergantungan khusus? Tolong jelaskan
Zoe
1
Pembuat java memutuskan bahwa masalah multiple inheritance lebih besar daripada manfaatnya, jadi mereka tidak menyertakan multiple inheritance. Anda dapat membaca tentang salah satu masalah terbesar dari multiple inheritance (masalah berlian ganda) di sini .
Dua konsep yang paling mirip adalah implementasi antarmuka dan termasuk objek dari kelas lain sebagai anggota kelas saat ini. Menggunakan metode default di antarmuka hampir persis sama dengan multiple inheritance, namun dianggap praktik yang buruk untuk menggunakan antarmuka dengan metode standar saja.
Jawaban:
Anda hanya dapat Perpanjang satu kelas. Dan mengimplementasikan Antarmuka dari banyak sumber.
Memperluas beberapa kelas tidak tersedia. Satu-satunya solusi yang dapat saya pikirkan adalah tidak mewarisi kelas mana pun melainkan memiliki variabel internal masing-masing kelas dan melakukan lebih banyak proxy dengan mengarahkan permintaan ke objek Anda ke objek yang Anda inginkan.
ini adalah solusi terbaik yang saya miliki. Anda bisa mendapatkan fungsionalitas dari kedua kelas dan Masih hanya benar-benar satu jenis kelas.
Kekurangannya adalah bahwa Anda tidak dapat masuk ke dalam Cetakan kelas Internal menggunakan gips.
sumber
Mengapa Tidak Menggunakan Kelas Batin (Bersarang)
sumber
Fragment
. Aktivitas saya harus diperluasFragment
, yang berarti saya benar-benar perlugetView()
, yang tidak akan berfungsi jika itu di dalam kelas batin, dan kode di sana adalah tempat saya perlu menggunakan kodeListActivity
, jadi saya tidak dapat memperluas dua kali, ATAU melakukan kelas dalam dalam contoh ini.Seperti yang dikatakan semua orang. Tidak bisa. Namun, meskipun orang telah mengatakan berkali-kali selama bertahun-tahun bahwa Anda harus menggunakan banyak antarmuka, mereka belum benar-benar memahami caranya. Semoga ini bisa membantu.
Katakanlah Anda memiliki
class Foo
danclass Bar
bahwa Anda berdua ingin mencoba memperluas menjadi aclass FooBar
. Tentu saja, seperti yang Anda katakan, Anda tidak dapat melakukan:Orang sudah masuk ke alasan untuk ini sampai batas tertentu sudah. Sebagai gantinya, tulis
interfaces
untuk keduanyaFoo
danBar
mencakup semua metode publik mereka. MisalnyaDan sekarang membuat
Foo
danBar
mengimplementasikan antarmuka relatif:Sekarang, dengan
class FooBar
, Anda dapat menerapkan keduaFooInterface
danBarInterface
sekaligus menjagaFoo
danBar
objek dan hanya lewat metode langsung melalui:Bonus untuk metode ini, adalah bahwa
FooBar
objek cocok dengan cetakan keduanyaFooInterface
danBarInterface
. Itu berarti ini baik-baik saja:Semoga ini menjelaskan cara menggunakan antarmuka alih-alih beberapa ekstensi. Bahkan jika saya terlambat beberapa tahun.
sumber
Anda ingin menggunakan antarmuka. Secara umum, multiple inheritance buruk karena Masalah Berlian:
C ++ dan lainnya punya beberapa cara untuk menyelesaikan ini, mis
tetapi Java hanya menggunakan antarmuka.
Java Trails memiliki pengantar yang bagus tentang antarmuka: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Anda mungkin ingin mengikutinya sebelum masuk ke nuansa dalam API Android.
sumber
virtual class
. Melakukannya datang dengan banyak peringatan dan peringatan, baik untuk kompiler dan pengembang.super
dari metode pewarisan. Ya, Anda bisa, tetapi Anda harus menentukan metode antarmuka untuk memohon (dan harus menggunakan kata kuncidefault
dalam implementasi antarmuka) . Contohnya adalah: diMyIFace.super.foo()
mana MyIFace adalah antarmuka. Seperti yang Anda lihat metode antarmuka untuk mengeksekusi didefinisikan dan menghindari Masalah Diamond sepenuhnya. Jika Anda memperpanjangMyClass1
danMyClass2
, kedua kelas memilikifoo()
, dan memanggilsuper.foo()
kemudian kompiler dilempar oleh Masalah Diamond."bar"
atau"baz"
dengan tipe metodevoid
. Bagaimanapun, penjelasan yang baik xDYa, seperti yang ditulis semua orang, Anda tidak dapat melakukan banyak pewarisan di Jawa. Jika Anda memiliki dua kelas dari mana Anda ingin menggunakan kode, Anda biasanya hanya subkelas satu (katakanlah kelas
A
). Untuk kelasB
, Anda abstrak metode penting itu ke antarmukaBInterface
(nama jelek, tetapi Anda mendapatkan ide), lalu katakanMain extends A implements BInterface
. Di dalam, Anda dapat membuat instance objek kelasB
dan menerapkan semua metodeBInterface
dengan memanggil fungsi yang sesuaiB
.Ini mengubah hubungan "is-a" menjadi hubungan "has-a" seperti
Main
sekarangA
, tetapi memilikiB
. Tergantung pada kasus penggunaan Anda, Anda bahkan dapat membuat perubahan itu secara eksplisit dengan menghapusBInterface
dariA
kelas Anda dan sebagai gantinya memberikan metode untuk mengakses objek B Anda secara langsung.sumber
Buat antarmuka. Java tidak memiliki banyak pewarisan.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
sumber
Java tidak mendukung multiple inheritance, tetapi Anda dapat mencoba mengimplementasikan dua atau lebih antarmuka.
sumber
Iya. fitnah benar. Java tidak mengizinkan perluasan dari beberapa kelas.
Apa yang Anda inginkan mungkin
public class Main extends ListActivity implements ControlMenu
. Saya kira Anda mencoba membuat daftar.Semoga itu bisa membantu.
sumber
Seperti alternatif lain, mungkin Anda dapat menggunakan antarmuka dengan implementasi metode standar. Itu tentu saja tergantung dari apa yang ingin Anda lakukan.
Misalnya, Anda bisa membuat kelas abstrak dan antarmuka:
Jadi, setelah itu, Anda bisa memperluas dan mengimplementasikan kedua kelas dan menggunakan kedua metode.
Semoga ini bisa membantu Anda ...
sumber
Memperluas dari beberapa kelas tidak diperbolehkan di java .. untuk mencegah Deadly Diamond of death !
sumber
itu mungkin
sumber
Parallaxor
danParallaxController
tidak diketahui, jadi saya berasumsi mereka bukan kelas-SDK. Jadi ini tidak berfungsi untuk saya (dan dengan demikian jawaban ini menunjukkan kesalahan). Apa itu ParallaxController? Apakah ini ketergantungan khusus? Tolong jelaskanPembuat java memutuskan bahwa masalah multiple inheritance lebih besar daripada manfaatnya, jadi mereka tidak menyertakan multiple inheritance. Anda dapat membaca tentang salah satu masalah terbesar dari multiple inheritance (masalah berlian ganda) di sini .
Dua konsep yang paling mirip adalah implementasi antarmuka dan termasuk objek dari kelas lain sebagai anggota kelas saat ini. Menggunakan metode default di antarmuka hampir persis sama dengan multiple inheritance, namun dianggap praktik yang buruk untuk menggunakan antarmuka dengan metode standar saja.
sumber
Anda tidak dapat melakukan banyak pewarisan di java. pertimbangkan menggunakan antarmuka:
atau kelas batin:
sumber