Кроме того, я хотел бы знать, что с этим подходом все в порядке, что я создал меню в классе, который называется ControlMenu, и я расширяю остальные действия.
Вы не можете продлить два или более классов одновременно. Множественное наследование не допускается в Java.
Йогма
Ответы:
156
Вы можете продлить только один класс. И реализовать интерфейсы из многих источников.
Продление нескольких классов недоступно. Единственное решение, которое я могу придумать, это не наследовать ни один из классов, а вместо этого иметь внутреннюю переменную каждого класса и делать больше прокси, перенаправляя запросы к вашему объекту на объект, к которому вы хотите, чтобы они пошли.
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();}}
это лучшее решение, которое я придумал. Вы можете получить функциональность от обоих классов, и все же только на самом деле быть одного типа класса.
Недостатком является то, что вы не можете вписаться в класс Mold of Internal, используя приведение.
Интересный подход, что эксперты думают об этой технике? Я хотел бы покопаться в этом.
TechNyquist
1
Это нормально с конвенциями?
сегодня,
2
Не удалось получить внутренний класс для работы в Fragment. Моя деятельность должна расширяться Fragment, а это значит, что мне это абсолютно необходимо getView(), что не будет работать, если оно находится внутри внутреннего класса, и код там, где мне нужно использовать код ListActivity, поэтому я не могу расширяться дважды, ИЛИ делать внутренний класс в этом примере.
Azurespot
Это лучшее решение для расширения абстрактных классов, где вам нужен доступ к переменным класса.
tak3shi
45
Как все говорили. Нет, ты не можешь. Однако, несмотря на то, что люди много раз говорили на протяжении многих лет, что вы должны использовать несколько интерфейсов, они на самом деле не понимали, как это сделать. Надеюсь, это поможет.
Скажем, у вас есть class Fooи class Barчто вы оба хотите попробовать расширить в class FooBar. Конечно, как вы сказали, вы не можете сделать:
publicclassFooBarextendsFoo,Bar
Люди уже в какой-то степени разбираются в причинах этого. Вместо этого пишите interfacesдля обоих Fooи Barохватывая все их публичные методы. Например
Теперь, class FooBarвы можете реализовать как FooInterfaceи BarInterfaceсохраняя при этом Fooи Barобъект и только проездом методы прямо через:
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);}//...}
Бонус для этого метода заключается в том, что FooBarобъект соответствует шаблонам как FooInterfaceи BarInterface. Это означает, что это прекрасно:
Это очень хороший ответ, однако я вижу в нем пару проблем, которые необходимо рассмотреть более подробно. Во-первых, расширение из двух существующих классов было бы немного более проблематичным, и было бы множество дополнительных препятствий, которые нужно преодолеть. Во-вторых, если бы интерфейс Foo и Bar имели одинаковые функции, вам необходимо иметь порядок приоритетов. Явное расширение вашего класса заставит вас принимать эти решения заранее. Еще отличный вариант :) +1
Ленивый кодер
Что если нам нужно «часто» создавать новые классы и заставлять каждый из этих классов реализовывать оба интерфейса? Затем мы должны будем повторить эти стандартные реализации в каждом классе. Есть ли лучший способ заставить класс «реализовать» два набора поведения?
MasterJoe2
1
@ MasterJoe2 Честно говоря, я уже давно не очень много пользуюсь Java (я остановился, когда писал этот ответ). Одна из причин, по которой я избегаю этого сейчас, - это та самая проблема, которую вы поднимаете. Предсказание направления, которое вы могли бы исследовать, - написание абстрактного класса, который реализует оба интерфейса и расширяет его. Однако я понятия не имею, верна ли это Java, и чувствую, что вы просто столкнетесь с той же самой первоначальной проблемой, когда захотите внести изменения в реализующий класс в будущем. Извините, я не могу больше помочь.
SCB
37
Вы хотите использовать интерфейсы. Как правило, множественное наследование плохо из-за проблемы с бриллиантами:
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 ++ и другие имеют несколько способов решить эту проблему, например
Я никогда не понимал, почему проблема алмазов на самом деле является проблемой, которая предотвращает множественное наследование. Почему компилятор не может просто жаловаться, если есть конфликтующие методы с тем же именем?
Пит
1
Для достаточно умных компиляторов это не так. Решение на уровне компилятора возможно, и в действительности C ++ делает это с помощью virtual class. Это сопровождается множеством предупреждений и предостережений как для компилятора, так и для разработчика.
Дэвид Саутер
1
Как насчет тех же методов по умолчанию в двух интерфейсах? Это еще один пример алмазной проблемы, с которой может справиться Java.
Вы не можете вернуть "bar"или "baz"с методом типа void. В любом случае, хорошее объяснение xD
xdevs23
22
Да, как и все остальные, вы не можете делать множественное наследование в Java. Если у вас есть два класса, из которых вы хотите использовать код, вы обычно просто подкласс один (скажем, класс A). Для класса Bвы абстрагируете его важные методы в интерфейс BInterface(некрасивое имя, но вы поняли), а затем говорите Main extends A implements BInterface. Внутри вы можете создать экземпляр объекта класса Bи реализовать все методы BInterface, вызывая соответствующие функции B.
Это меняет отношение «есть» на отношение «есть», которое есть у вас Mainсейчас A, но есть B. В зависимости от вашего варианта использования, вы можете даже сделать это изменение явным, удалив BInterfaceиз вашего Aкласса и вместо этого предоставив метод для прямого доступа к вашему объекту B.
ауу почему понизить? Я не был злым, я просто думаю, что он мог позволить себе немного почитать и подумать о проблеме самостоятельно, прежде чем мы построим его уроки для него
slandau
6
Java не поддерживает множественное наследование, но вы можете попробовать реализовать два или более интерфейса.
Как и другая альтернатива, возможно, вы можете использовать интерфейс с реализацией метода по умолчанию. Это зависит, конечно, от того, что вы хотите сделать.
Например, вы можете создать абстрактный класс и интерфейс:
publicabstractclassFatherClass{abstractvoid methodInherit(){//... do something}}publicinterfaceInterfaceWithDefaultsMethods{defaultvoid anotherMethod(){//... do something//... maybe a method with a callable for call another function.}}
Таким образом, после этого вы можете расширять и реализовывать оба класса и использовать оба метода.
Parallaxorи ParallaxControllerнеизвестны, поэтому я предполагаю, что они не являются SDK-классами. Так что это не работает для меня (и, следовательно, этот ответ показывает ошибки). Что такое ParallaxController? Это специфическая зависимость? Пожалуйста, уточните
Зоя
1
Создатели Java решили, что проблемы множественного наследования перевешивают преимущества, поэтому они не включали множественное наследование. Вы можете прочитать об одной из самых больших проблем множественного наследования (проблема двойного ромба) здесь .
Двумя наиболее похожими концепциями являются реализация интерфейса и включение объектов других классов в члены текущего класса. Использование методов по умолчанию в интерфейсах почти такое же, как множественное наследование, однако считается плохой практикой использовать интерфейс только с методами по умолчанию.
Ответы:
Вы можете продлить только один класс. И реализовать интерфейсы из многих источников.
Продление нескольких классов недоступно. Единственное решение, которое я могу придумать, это не наследовать ни один из классов, а вместо этого иметь внутреннюю переменную каждого класса и делать больше прокси, перенаправляя запросы к вашему объекту на объект, к которому вы хотите, чтобы они пошли.
это лучшее решение, которое я придумал. Вы можете получить функциональность от обоих классов, и все же только на самом деле быть одного типа класса.
Недостатком является то, что вы не можете вписаться в класс Mold of Internal, используя приведение.
источник
Почему бы не использовать внутренний класс (вложение)
источник
Fragment
. Моя деятельность должна расширятьсяFragment
, а это значит, что мне это абсолютно необходимоgetView()
, что не будет работать, если оно находится внутри внутреннего класса, и код там, где мне нужно использовать кодListActivity
, поэтому я не могу расширяться дважды, ИЛИ делать внутренний класс в этом примере.Как все говорили. Нет, ты не можешь. Однако, несмотря на то, что люди много раз говорили на протяжении многих лет, что вы должны использовать несколько интерфейсов, они на самом деле не понимали, как это сделать. Надеюсь, это поможет.
Скажем, у вас есть
class Foo
иclass Bar
что вы оба хотите попробовать расширить вclass FooBar
. Конечно, как вы сказали, вы не можете сделать:Люди уже в какой-то степени разбираются в причинах этого. Вместо этого пишите
interfaces
для обоихFoo
иBar
охватывая все их публичные методы. НапримерА теперь сделайте
Foo
иBar
реализуйте соответствующие интерфейсы:Теперь,
class FooBar
вы можете реализовать какFooInterface
иBarInterface
сохраняя при этомFoo
иBar
объект и только проездом методы прямо через:Бонус для этого метода заключается в том, что
FooBar
объект соответствует шаблонам какFooInterface
иBarInterface
. Это означает, что это прекрасно:Надеюсь, что это проясняет, как использовать интерфейсы вместо нескольких расширений. Даже если я опоздал на несколько лет.
источник
Вы хотите использовать интерфейсы. Как правило, множественное наследование плохо из-за проблемы с бриллиантами:
C ++ и другие имеют несколько способов решить эту проблему, например
но Java использует только интерфейсы.
В Java Trails есть отличное введение в интерфейсы: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Возможно, вы захотите следовать этому, прежде чем углубляться в нюансы в API Android.
источник
virtual class
. Это сопровождается множеством предупреждений и предостережений как для компилятора, так и для разработчика.super
из метода в наследовании. Ну, вы можете, но вы должны указать метод интерфейса для вызова (и он должен использовать ключевое словоdefault
в реализации интерфейса) . Пример:MyIFace.super.foo()
где MyIFace является интерфейсом. Как вы можете видеть, интерфейсный метод, который нужно выполнить, определен и полностью исключает проблему Diamond. Если вы расширяетеMyClass1
иMyClass2
, оба класса имеютfoo()
, и вызов,super.foo()
то компилятор выбрасывается Алмазной проблемой."bar"
или"baz"
с методом типаvoid
. В любом случае, хорошее объяснение xDДа, как и все остальные, вы не можете делать множественное наследование в Java. Если у вас есть два класса, из которых вы хотите использовать код, вы обычно просто подкласс один (скажем, класс
A
). Для классаB
вы абстрагируете его важные методы в интерфейсBInterface
(некрасивое имя, но вы поняли), а затем говоритеMain extends A implements BInterface
. Внутри вы можете создать экземпляр объекта классаB
и реализовать все методыBInterface
, вызывая соответствующие функцииB
.Это меняет отношение «есть» на отношение «есть», которое есть у вас
Main
сейчасA
, но естьB
. В зависимости от вашего варианта использования, вы можете даже сделать это изменение явным, удаливBInterface
из вашегоA
класса и вместо этого предоставив метод для прямого доступа к вашему объекту B.источник
Сделай интерфейс. У Java нет множественного наследования.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
источник
Java не поддерживает множественное наследование, но вы можете попробовать реализовать два или более интерфейса.
источник
Да. Сландау прав. Java не позволяет расширяться из нескольких классов.
То, что вы хотите, это, вероятно,
public class Main extends ListActivity implements ControlMenu
. Я предполагаю, что вы пытаетесь составить список.Надеюсь, это поможет.
источник
Как и другая альтернатива, возможно, вы можете использовать интерфейс с реализацией метода по умолчанию. Это зависит, конечно, от того, что вы хотите сделать.
Например, вы можете создать абстрактный класс и интерфейс:
Таким образом, после этого вы можете расширять и реализовывать оба класса и использовать оба метода.
Надеюсь, это поможет вам ...
источник
Расширение из нескольких классов не допускается в Java .. чтобы предотвратить Смертельный Бриллиант смерти !
источник
это возможно
источник
Parallaxor
иParallaxController
неизвестны, поэтому я предполагаю, что они не являются SDK-классами. Так что это не работает для меня (и, следовательно, этот ответ показывает ошибки). Что такое ParallaxController? Это специфическая зависимость? Пожалуйста, уточнитеСоздатели Java решили, что проблемы множественного наследования перевешивают преимущества, поэтому они не включали множественное наследование. Вы можете прочитать об одной из самых больших проблем множественного наследования (проблема двойного ромба) здесь .
Двумя наиболее похожими концепциями являются реализация интерфейса и включение объектов других классов в члены текущего класса. Использование методов по умолчанию в интерфейсах почти такое же, как множественное наследование, однако считается плохой практикой использовать интерфейс только с методами по умолчанию.
источник
Вы не можете сделать множественное наследование в Java. рассмотреть возможность использования интерфейсов:
или внутренние классы:
источник