W jaki sposób mogę to zrobić:
public class Main extends ListActivity , ControlMenu
Chciałbym również wiedzieć, czy to podejście jest w porządku, że stworzyłem menu w klasie ControlMenu i rozszerzam pozostałe czynności.
W jaki sposób mogę to zrobić:
public class Main extends ListActivity , ControlMenu
Chciałbym również wiedzieć, czy to podejście jest w porządku, że stworzyłem menu w klasie ControlMenu i rozszerzam pozostałe czynności.
Odpowiedzi:
Możesz rozszerzyć tylko jedną klasę. I implementuj interfejsy z wielu źródeł.
Przedłużanie wielu klas nie jest dostępne. Jedynym rozwiązaniem, które przychodzi mi do głowy, nie jest dziedziczenie żadnej z klas, ale zamiast tego posiadanie wewnętrznej zmiennej każdej klasy i robienie więcej z proxy, przekierowując żądania do obiektu do obiektu, do którego mają trafiać.
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();
}
}
to najlepsze rozwiązanie, jakie wymyśliłem. Możesz uzyskać funkcjonalność z obu klas, a nadal może być tylko jednego typu.
Wadą jest to, że nie można dopasować się do klasy formy wewnętrznej za pomocą odlewu.
Dlaczego nie użyć klasy wewnętrznej (zagnieżdżanie)
class A extends B {
private class C extends D {
//Classes A , B , C , D accessible here
}
}
Fragment. Moja aktywność musi się rozszerzać Fragment, co oznacza, że absolutnie potrzebuję getView(), co nie zadziała, jeśli znajduje się w klasie wewnętrznej, a kod tam jest, z którego muszę użyć kodu ListActivity, więc nie mogę dwukrotnie rozszerzyć LUB zrobić klasy wewnętrznej w tym przykładzie.
Jak wszyscy powiedzieli. Nie, nie możesz. Jednak nawet jeśli ludzie wielokrotnie powtarzali przez lata, że powinieneś używać wielu interfejsów, tak naprawdę nie wnikali w to, jak to zrobić. Mam nadzieję, że to pomoże.
Powiedzmy, że masz class Fooi class Baroboje chcecie spróbować rozszerzyć do class FooBar. Oczywiście, jak powiedziałeś, nie możesz:
public class FooBar extends Foo, Bar
Ludzie do pewnego stopnia już wnikali w przyczyny takiego stanu rzeczy. Zamiast tego napisz interfacesdla obu Fooi Baromów wszystkie ich publiczne metody. Na przykład
public interface FooInterface {
public void methodA();
public int methodB();
//...
}
public interface BarInterface {
public int methodC(int i);
//...
}
A teraz stwórz Fooi Barzaimplementuj odpowiednie interfejsy:
public class Foo implements FooInterface { /*...*/ }
public class Bar implements BarInterface { /*...*/ }
Teraz, z class FooBar, można realizować zarówno FooInterfacei BarInterfaceprzy zachowaniu Fooi Barobiekt i tylko przejazdem metody prosto przez:
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);
}
//...
}
Zaletą tej metody jest to, że FooBarprzedmiot pasuje do formy zarówno FooInterfacei BarInterface. Oznacza to, że wszystko jest w porządku:
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);
Mam nadzieję, że to wyjaśnia, jak używać interfejsów zamiast wielu rozszerzeń. Nawet jeśli spóźnię się kilka lat.
Będziesz chciał używać interfejsów. Generalnie dziedziczenie wielokrotne jest złe z powodu problemu diamentowego:
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 ++ i inne mają kilka sposobów rozwiązania tego problemu, np
string foo() { return B::foo(); }
ale Java używa tylko interfejsów.
Ścieżki Java mają świetne wprowadzenie do interfejsów: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Prawdopodobnie zechcesz to prześledzić, zanim zagłębisz się w niuanse w Android API.
virtual class. Takie postępowanie wiąże się z wieloma ostrzeżeniami i zastrzeżeniami, zarówno dla kompilatora, jak i programisty.
superfrom w dziedziczeniu metody. Cóż, możesz, ale musisz określić metodę interfejsu do wywołania (i musi ona użyć słowa kluczowego defaultw implementacji interfejsu) . Przykład: MyIFace.super.foo()gdzie MyIFace jest interfejsem. Jak widać, metoda interfejsu do wykonania jest zdefiniowana i całkowicie pozwala uniknąć problemu diamentów. Jeśli rozszerzysz MyClass1i MyClass2, obie klasy mają a foo(), i wywołasz, super.foo()kompilator zostanie zgłoszony przez Diamentowy Problem.
"bar"ani "baz"z typem metody void. W każdym razie, dobre wyjaśnienie xD
Tak, jak wszyscy pisali, w Javie nie można dziedziczyć wielokrotnego. Jeśli masz dwie klasy, z których chciałbyś użyć kodu, zwykle tworzysz podklasę jedną (powiedzmy class A). W przypadku klasy B, przenosisz ważne metody do interfejsu BInterface(brzydka nazwa, ale masz pomysł), a następnie mówisz Main extends A implements BInterface. Wewnątrz możesz utworzyć instancję obiektu klasy Bi zaimplementować wszystkie metody programu BInterface, wywołując odpowiednie funkcje B.
Zmienia to relację „jest-a” w relację „ma-a”, ponieważ twoje Mainteraz jest A, ale ma B. W zależności od przypadku użycia możesz nawet wprowadzić tę zmianę jawnie, usuwając element BInterfacez Aklasy i zamiast tego udostępnić metodę bezpośredniego dostępu do obiektu B.
Stwórz interfejs. Java nie ma wielokrotnego dziedziczenia.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
Java nie obsługuje dziedziczenia wielokrotnego, ale możesz spróbować zaimplementować dwa lub więcej interfejsów.
Podobnie jak inna alternatywa, być może możesz użyć interfejsu z domyślną implementacją metody. To oczywiście zależy od tego, co chcesz zrobić.
Na przykład możesz utworzyć klasę abstrakcyjną i interfejs:
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.
}
}
Następnie możesz rozszerzyć i zaimplementować obie klasy i użyć obu metod.
public class extends FatherClass implements InterfaceWithDefaultsMethods {
void methode() {
methodInherit();
anotherMethod();
}
}
Mam nadzieję, że to ci pomoże ...
Rozszerzanie z wielu klas nie jest dozwolone w Javie, aby zapobiec Deadly Diamond of death !
to jest możliwe
public class ParallaxViewController<T extends View & Parallaxor> extends ParallaxController<T> implements AbsListView.OnScrollListener {
//blah
}
Parallaxori ParallaxControllersą nieznane, więc zakładam, że nie są to klasy SDK. Więc to nie działa dla mnie (i dlatego ta odpowiedź pokazuje błędy). Co to jest ParallaxController? Czy to jest konkretna zależność? Proszę rozwinąć
Twórcy javy zdecydowali, że problemy wielokrotnego dziedziczenia przeważają nad korzyściami, więc nie uwzględnili dziedziczenia wielokrotnego. Możesz przeczytać o jednym z największych problemów związanych z dziedziczeniem wielokrotnym (problem podwójnego diamentu) tutaj .
Dwie najbardziej podobne koncepcje to implementacja interfejsu i dołączanie obiektów innych klas jako elementów składowych bieżącej klasy. Używanie metod domyślnych w interfejsach jest prawie dokładnie tym samym, co dziedziczenie wielokrotne, jednak używanie interfejsu tylko z metodami domyślnymi jest uważane za złą praktykę.
nie możesz zrobić wielokrotnego dziedziczenia w java. rozważ użycie interfejsów:
interface I1 {}
interface I2 {}
class C implements I1, I2 {}
lub klasy wewnętrzne:
class Outer {
class Inner1 extends Class1 {}
class Inner2 extends Class2 {}
}