Bunu nasıl yapabilirim:
public class Main extends ListActivity , ControlMenu
Ayrıca, bu yaklaşımın, menülerde ControlMenu olan sınıfta yaptığımın iyi olduğunu bilmek istiyorum ve aktivitelerin geri kalanında uzanıyorum.
Bunu nasıl yapabilirim:
public class Main extends ListActivity , ControlMenu
Ayrıca, bu yaklaşımın, menülerde ControlMenu olan sınıfta yaptığımın iyi olduğunu bilmek istiyorum ve aktivitelerin geri kalanında uzanıyorum.
Yanıtlar:
Yalnızca tek bir sınıfı genişletebilirsiniz. Ve birçok kaynaktan arayüzler uygulayın.
Birden fazla sınıfı genişletmek mümkün değildir. Düşünebildiğim tek çözüm, her iki sınıfı da miras almak değil, her sınıfın dahili değişkenine sahip olmak ve isteklerinizi nesnenize gitmelerini istediğiniz nesneye yönlendirerek daha fazla proxy yapmaktır.
public class CustomActivity extends Activity {
private AnotherClass mClass;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mClass = new AnotherClass(this);
}
//Implement each method you want to use.
public String getInfoFromOtherClass()
{
return mClass.getInfoFromOtherClass();
}
}
bu benim en iyi çözümüm. Her iki sınıftan da işlevsellik alabilirsiniz ve yine de yalnızca bir sınıf türünde olabilirsiniz.
Dezavantajı, bir döküm kullanarak Dahili sınıfın Kalıp içine sığamaz olmasıdır.
Neden İç Sınıf Kullanmıyorsunuz (Yerleştirme)
class A extends B {
private class C extends D {
//Classes A , B , C , D accessible here
}
}
Fragment. Etkinliğim uzatılmalı Fragment, yani kesinlikle ihtiyacım var getView(), bu iç sınıfta ise işe yaramaz ve içindeki koddan kod kullanmam gereken yer ListActivity, bu yüzden iki kez uzatamıyorum, VEYA bir iç sınıf yapıyorum bu örnekte.
Herkesin söylediği gibi. Hayır, yapamazsınız. Bununla birlikte, insanlar yıllar boyunca birçok kez birden fazla arayüz kullanmanız gerektiğini söylemiş olsalar da, gerçekten nasıl olduklarına girmediler. Umarım bu yardımcı olacaktır.
Sahip olduğunuzu class Foove class Barher ikinizin de a class FooBar. Tabii ki, dediğin gibi yapamazsın:
public class FooBar extends Foo, Bar
İnsanlar zaten bir dereceye kadar bunun nedenlerine girdiler. Bunun yerine, interfacesher ikisi için de yazın Foove Bartüm kamu yöntemlerini kapsar. Örneğin
public interface FooInterface {
public void methodA();
public int methodB();
//...
}
public interface BarInterface {
public int methodC(int i);
//...
}
Ve şimdi göreli arayüzleri yapın Foove Baruygulayın:
public class Foo implements FooInterface { /*...*/ }
public class Bar implements BarInterface { /*...*/ }
Şimdi, ile class FooBar, her iki uygulayabilirsiniz FooInterfaceve BarInterfacebir tutarken Foove Barnesne ve sadece içinden düz yöntemleri geçen:
public class FooBar implements FooInterface, BarInterface {
Foo myFoo;
Bar myBar;
// You can have the FooBar constructor require the arguments for both
// the Foo and the Bar constructors
public FooBar(int x, int y, int z){
myFoo = new Foo(x);
myBar = new Bar(y, z);
}
// Or have the Foo and Bar objects passed right in
public FooBar(Foo newFoo, Bar newBar){
myFoo = newFoo;
myBar = newBar;
}
public void methodA(){
myFoo.methodA();
}
public int methodB(){
return myFoo.methodB();
}
public int methodC(int i){
return myBar.methodC(i);
}
//...
}
Bu yöntemin avantajı, FooBarnesnenin hem FooInterfaceve hem de kalıplarına uymasıdır BarInterface. Bunun anlamı gayet iyi:
FooInterface testFoo;
testFoo = new FooBar(a, b, c);
testFoo = new Foo(a);
BarInterface testBar;
testBar = new FooBar(a, b, c);
testBar = new Bar(b, c);
Umarım bu, çoklu uzantılar yerine arayüzlerin nasıl kullanılacağını açıklar. Birkaç yıl geç kalsam bile.
Arayüzler kullanmak isteyeceksiniz. Genel olarak, Elmas Sorunu nedeniyle çoklu kalıtım kötüdür:
abstract class 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() { return super.foo(); } //What do I do? Which method should I call?
}
C ++ ve diğerlerinin bunu çözmek için birkaç yolu vardır, örn.
string foo() { return B::foo(); }
ancak Java yalnızca arabirimler kullanır.
Java Parkurları arayüzler hakkında harika bir giriş yapar: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Android API'sındaki nüanslara dalmadan önce muhtemelen bunu takip etmek isteyeceksiniz.
virtual class. Bunu yapmak, derleyici ve geliştirici için birçok uyarı ve uyarı ile birlikte gelir.
super, miras kalan bir yöntemden çağrı yapmazsınız. Evet, ancak çağırılacak arabirim yöntemini belirtmeniz gerekir (ve defaultarabirim uygulamasında anahtar sözcüğü kullanması gerekir ) . Bir örnek: MyIFace.super.foo()burada MyIFace bir arayüzdür. Gördüğünüz gibi yürütmek için arabirim yöntemi tanımlanmış ve Elmas Sorunu tamamen önler. Genişletirseniz MyClass1ve MyClass2her iki sınıfta da a foo()ve çağrı super.foo()varsa derleyici Elmas Sorunu tarafından atılır.
"bar"veya "baz"yöntem türü ile void. Neyse, iyi bir açıklama xD
Evet, herkesin yazdığı gibi, Java'da çoklu kalıtım yapamazsınız. Kodunu kullanmak istediğiniz iki sınıfınız varsa, genellikle yalnızca bir alt sınıf (sınıf diyelim A) olur. Sınıf için B, bunun önemli yöntemlerini bir arayüze BInterface(çirkin ad, ama fikri anlıyorsunuz) soyutlarsınız , sonra söyleyin Main extends A implements BInterface. İçeride, bir sınıf nesnesini başlatabilir ve ilgili işlevlerini çağırarak Btüm yöntemlerini uygulayabilirsiniz .BInterfaceB
Bu, Mainşu anki gibi bir "has-a" ilişkisini "has-a" ilişkisiyle değiştirir A, ancak bir B. Kullanımı durumda bağlı olarak, hatta kaldırarak bu değişiklik açık hale getirebileceğini BInterfacesizin gelen Asınıf ve yerine doğrudan B nesnesi erişmek için bir yöntem sağlar.
Bir arayüz oluşturun. Java'nın birden fazla mirası yoktur.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
Java, birden fazla kalıtımı desteklemez, ancak iki veya daha fazla arabirimi uygulamayı deneyebilirsiniz.
Başka bir alternatif gibi, belki de bir yöntemin varsayılan uygulaması olan bir arabirim kullanabilirsiniz. Bu elbette ne yapmak istediğinize bağlıdır.
Örneğin, soyut bir sınıf ve bir arayüz oluşturabilirsiniz:
public abstract class FatherClass {
abstract void methodInherit() {
//... do something
}
}
public interface InterfaceWithDefaultsMethods {
default void anotherMethod() {
//... do something
//... maybe a method with a callable for call another function.
}
}
Bundan sonra, her iki sınıfı genişletebilir ve uygulayabilir ve her iki yöntemi de kullanabilirsiniz.
public class extends FatherClass implements InterfaceWithDefaultsMethods {
void methode() {
methodInherit();
anotherMethod();
}
}
Umarım bu sana yardımcı olur ...
Ölümcül Elmas ölüm önlemek için java .. birden fazla sınıftan genişletilmesi yasaktır !
bu mümkün
public class ParallaxViewController<T extends View & Parallaxor> extends ParallaxController<T> implements AbsListView.OnScrollListener {
//blah
}
Parallaxorve ParallaxControllerbilinmiyor, bu yüzden SDK sınıfı olmadığını düşünüyorum. Bu benim için işe yaramıyor (ve dolayısıyla bu cevap hataları gösteriyor). ParallaxController nedir? Bu belirli bir bağımlılık mı? Lütfen detaylandırın
Java'nın yaratıcıları, çoklu miras sorunlarının faydalardan daha ağır bastığına karar verdiler, bu nedenle çoklu miras içermediler. Burada çoklu kalıtımın en büyük sorunlarından birini (çift elmas sorunu) okuyabilirsiniz .
En benzer iki kavram, arabirim uygulamasıdır ve mevcut sınıfın üyeleri olarak diğer sınıfların nesnelerini içerir. Arabirimlerde varsayılan yöntemleri kullanmak, çoklu kalıtımla neredeyse aynıdır, ancak yalnızca varsayılan yöntemlerle bir arabirim kullanmak kötü bir uygulama olarak kabul edilir.
java'da çoklu kalıtım yapamazsınız. arayüzleri kullanmayı düşünün:
interface I1 {}
interface I2 {}
class C implements I1, I2 {}
veya iç sınıflar:
class Outer {
class Inner1 extends Class1 {}
class Inner2 extends Class2 {}
}