Além disso, gostaria de saber que, se essa abordagem for aceitável, criei os menus na classe ControlMenu e estarei estendendo o restante das atividades.
Você não pode estender duas ou mais aulas ao mesmo tempo. Herança múltipla não é permitida em java.
Yogma
Respostas:
156
Você pode estender apenas uma única classe. E implemente interfaces de várias fontes.
A extensão de várias classes não está disponível. A única solução em que consigo pensar é não herdar nenhuma das classes, mas sim ter uma variável interna de cada classe e fazer mais proxy, redirecionando as solicitações ao seu objeto para o objeto que você deseja que elas acessem.
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();}}
esta é a melhor solução que eu encontrei. Você pode obter a funcionalidade de ambas as classes e ainda ser realmente apenas de um tipo de classe.
A desvantagem é que você não pode se encaixar no molde da classe Interna usando um molde.
Abordagem interessante, o que os especialistas pensam dessa técnica? Eu gostaria de cavar.
TechNyquist
1
Tudo bem com as convenções?
obtido em 25/07/2014
2
Não foi possível obter a classe interna para trabalhar em um Fragment. Minha atividade deve se estender Fragment, o que significa que eu absolutamente preciso getView(), o que não funcionará se estiver dentro da classe interna, e o código é o local de onde eu preciso usar o código ListActivity, então não posso estender duas vezes OU faça uma classe interna neste exemplo.
Azurespot 13/03/2015
Esta é a melhor solução para estender as classes abstratas nas quais você precisa acessar as variáveis da classe que está implementando.
Tak3shi
45
Como todo mundo já disse. Não, você não pode. No entanto, mesmo que as pessoas tenham dito muitas vezes ao longo dos anos que você deve usar várias interfaces, elas realmente não entenderam como. Espero que isso ajude.
Digamos que você tenha class Fooe class Barque ambos desejam tentar estender-se para a class FooBar. Obviamente, como você disse, você não pode fazer:
publicclassFooBarextendsFoo,Bar
As pessoas já se debruçaram sobre as razões disso até certo ponto. Em vez disso, escreva interfacespara ambos Fooe Barcubra todos os seus métodos públicos. Por exemplo
Agora, com class FooBar, você pode implementar tanto FooInterfacee BarInterfaceao mesmo tempo manter um Fooe Barobjeto e apenas passando os métodos em linha reta através:
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);}//...}
O bônus para esse método é que o FooBarobjeto se encaixa nos moldes de ambos FooInterfacee BarInterface. Isso significa que está perfeitamente bem:
Esta é uma resposta muito boa, no entanto, vejo alguns problemas que precisariam ser abordados com mais detalhes. A primeira extensão de duas classes existentes seria um pouco mais problemática e haveria vários obstáculos extras a serem enfrentados. Segundo, se a interface Foo e Bar tiverem as mesmas funções, você precisará ter uma ordem de precedência. Estender explicitamente sua classe o forçaria a tomar essas decisões com antecedência. Ainda assim, excelente opção :) +1
The Lazy Coder
E se tivermos que criar novas classes "frequentemente" e fazer com que cada uma dessas classes implemente ambas as interfaces? Então, teríamos que repetir essas implementações padrão em cada classe. Existe uma maneira melhor de fazer uma classe "implementar" dois conjuntos de comportamentos?
MasterJoe2
1
@ MasterJoe2 Para ser sincero, não uso muito o Java há algum tempo (parei na época em que escrevi esta resposta). Uma das razões pelas quais evito isso hoje em dia é o próprio problema que você levanta. Um palpite para uma direção que você poderia investigar é escrever uma classe abstrata que implemente as duas interfaces e estenda isso. No entanto, não tenho idéia se o Java é válido e sinto que você acabará com o mesmo problema original quando quiser fazer alterações na classe de implementação no futuro. Desculpe, não posso ajudar mais.
SCB
37
Você vai querer usar interfaces. Geralmente, a herança múltipla é ruim por causa do problema do diamante:
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 ++ e outros têm algumas maneiras de resolver isso, por exemplo
Eu nunca entendi por que o problema do diamante é realmente um problema que impede a herança múltipla. Por que o compilador não pode simplesmente reclamar se existem métodos conflitantes com o mesmo nome?
Pete
1
Para compiladores suficientemente inteligentes, não é. É possível resolvê-lo no nível do compilador e, de fato, o C ++ o faz virtual class. Isso acontece com muitos avisos e advertências, tanto para o compilador quanto para o desenvolvedor.
David Souther
1
Que tal os mesmos métodos padrão em duas interfaces? Esse é outro exemplo do problema do diamante, com o qual o java pode lidar.
Você não pode retornar "bar"ou "baz"com o tipo de método de void. De qualquer forma, boa explicação xD
xdevs23
22
Sim, como todo mundo escreveu, você não pode fazer herança múltipla em Java. Se você tem duas classes das quais gostaria de usar o código, normalmente apenas subclasse uma (digamos classe A). Na aula B, você abstrai os métodos importantes para uma interface BInterface(nome feio, mas você entende) e depois diz Main extends A implements BInterface. Por dentro, você pode instanciar um objeto de classe Be implementar todos os métodos BInterfacechamando as funções correspondentes de B.
Isso altera o relacionamento "é-a" para um relacionamento "tem-a", pois o seu Mainagora é um A, mas possui um B. Dependendo do seu caso de uso, você pode até fazer essa mudança explícita, removendo o BInterfacedo seu Aclasse e sim fornecer um método para acessar o objeto B diretamente.
aww por que o voto negativo? Eu não estava sendo cruel, eu só acho que ele poderia dar ao luxo de fazer algumas leituras e pensar sobre o problema por conta própria antes de nós construir suas aulas para ele
slandau
6
Java não suporta herança múltipla, mas você pode tentar implementar duas ou mais interfaces.
Sim. Slandau está certo. Java não permite a extensão de várias classes.
O que você quer é provavelmente public class Main extends ListActivity implements ControlMenu. Eu estou supondo que você está tentando fazer uma lista.
Como outra alternativa, talvez você possa usar uma interface com a implementação padrão de um método. Isso depende, é claro, do que você deseja fazer.
Por exemplo, você pode criar uma classe abstrata e uma interface:
publicabstractclassFatherClass{abstractvoid methodInherit(){//... do something}}publicinterfaceInterfaceWithDefaultsMethods{defaultvoid anotherMethod(){//... do something//... maybe a method with a callable for call another function.}}
Então, depois disso, você pode estender e implementar as duas classes e usar os dois métodos.
Parallaxore ParallaxControllersão desconhecidos, então suponho que não sejam classes SDK. Portanto, isso não funciona para mim (e, portanto, esta resposta mostra erros). O que é o ParallaxController? Essa é uma dependência específica? Por favor, elabore
Zoe
1
Os criadores de java decidiram que os problemas de herança múltipla superam os benefícios, portanto, não incluíram herança múltipla. Você pode ler sobre um dos maiores problemas de herança múltipla (o problema do diamante duplo) aqui .
Os dois conceitos mais semelhantes são a implementação da interface e a inclusão de objetos de outras classes como membros da classe atual. O uso de métodos padrão em interfaces é quase exatamente o mesmo que herança múltipla, no entanto, é considerado uma prática ruim usar uma interface apenas com métodos padrão.
Respostas:
Você pode estender apenas uma única classe. E implemente interfaces de várias fontes.
A extensão de várias classes não está disponível. A única solução em que consigo pensar é não herdar nenhuma das classes, mas sim ter uma variável interna de cada classe e fazer mais proxy, redirecionando as solicitações ao seu objeto para o objeto que você deseja que elas acessem.
esta é a melhor solução que eu encontrei. Você pode obter a funcionalidade de ambas as classes e ainda ser realmente apenas de um tipo de classe.
A desvantagem é que você não pode se encaixar no molde da classe Interna usando um molde.
fonte
Por que não usar uma classe interna (aninhamento)
fonte
Fragment
. Minha atividade deve se estenderFragment
, o que significa que eu absolutamente precisogetView()
, o que não funcionará se estiver dentro da classe interna, e o código é o local de onde eu preciso usar o códigoListActivity
, então não posso estender duas vezes OU faça uma classe interna neste exemplo.Como todo mundo já disse. Não, você não pode. No entanto, mesmo que as pessoas tenham dito muitas vezes ao longo dos anos que você deve usar várias interfaces, elas realmente não entenderam como. Espero que isso ajude.
Digamos que você tenha
class Foo
eclass Bar
que ambos desejam tentar estender-se para aclass FooBar
. Obviamente, como você disse, você não pode fazer:As pessoas já se debruçaram sobre as razões disso até certo ponto. Em vez disso, escreva
interfaces
para ambosFoo
eBar
cubra todos os seus métodos públicos. Por exemploE agora faça
Foo
eBar
implemente as interfaces relativas:Agora, com
class FooBar
, você pode implementar tantoFooInterface
eBarInterface
ao mesmo tempo manter umFoo
eBar
objeto e apenas passando os métodos em linha reta através:O bônus para esse método é que o
FooBar
objeto se encaixa nos moldes de ambosFooInterface
eBarInterface
. Isso significa que está perfeitamente bem:Espero que isso esclareça como usar interfaces em vez de várias extensões. Mesmo se eu estiver atrasado alguns anos.
fonte
Você vai querer usar interfaces. Geralmente, a herança múltipla é ruim por causa do problema do diamante:
C ++ e outros têm algumas maneiras de resolver isso, por exemplo
mas Java usa apenas interfaces.
Os Java Trails têm uma ótima introdução às interfaces: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Você provavelmente desejará seguir isso antes de mergulhar nas nuances da API do Android.
fonte
virtual class
. Isso acontece com muitos avisos e advertências, tanto para o compilador quanto para o desenvolvedor.super
de em um método herdado. Bem, você pode, mas precisa especificar o método de interface a ser chamado (e deve usar a palavra-chavedefault
na implementação da interface) . Um exemplo é:MyIFace.super.foo()
onde MyIFace é uma interface. Como você pode ver, o método de interface a ser executado é definido e evita completamente o problema do diamante. Se você estenderMyClass1
eMyClass2
, ambas as classes tiverem umafoo()
chamada e,super.foo()
então o compilador será lançado pelo Problema de Diamante."bar"
ou"baz"
com o tipo de método devoid
. De qualquer forma, boa explicação xDSim, como todo mundo escreveu, você não pode fazer herança múltipla em Java. Se você tem duas classes das quais gostaria de usar o código, normalmente apenas subclasse uma (digamos classe
A
). Na aulaB
, você abstrai os métodos importantes para uma interfaceBInterface
(nome feio, mas você entende) e depois dizMain extends A implements BInterface
. Por dentro, você pode instanciar um objeto de classeB
e implementar todos os métodosBInterface
chamando as funções correspondentes deB
.Isso altera o relacionamento "é-a" para um relacionamento "tem-a", pois o seu
Main
agora é umA
, mas possui umB
. Dependendo do seu caso de uso, você pode até fazer essa mudança explícita, removendo oBInterface
do seuA
classe e sim fornecer um método para acessar o objeto B diretamente.fonte
Faça uma interface. Java não tem herança múltipla.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
fonte
Java não suporta herança múltipla, mas você pode tentar implementar duas ou mais interfaces.
fonte
Sim. Slandau está certo. Java não permite a extensão de várias classes.
O que você quer é provavelmente
public class Main extends ListActivity implements ControlMenu
. Eu estou supondo que você está tentando fazer uma lista.Espero que ajude.
fonte
Como outra alternativa, talvez você possa usar uma interface com a implementação padrão de um método. Isso depende, é claro, do que você deseja fazer.
Por exemplo, você pode criar uma classe abstrata e uma interface:
Então, depois disso, você pode estender e implementar as duas classes e usar os dois métodos.
Espero que isso ajude você...
fonte
A extensão de várias classes não é permitida no java .. para impedir a morte do diamante mortal !
fonte
é possível
fonte
Parallaxor
eParallaxController
são desconhecidos, então suponho que não sejam classes SDK. Portanto, isso não funciona para mim (e, portanto, esta resposta mostra erros). O que é o ParallaxController? Essa é uma dependência específica? Por favor, elaboreOs criadores de java decidiram que os problemas de herança múltipla superam os benefícios, portanto, não incluíram herança múltipla. Você pode ler sobre um dos maiores problemas de herança múltipla (o problema do diamante duplo) aqui .
Os dois conceitos mais semelhantes são a implementação da interface e a inclusão de objetos de outras classes como membros da classe atual. O uso de métodos padrão em interfaces é quase exatamente o mesmo que herança múltipla, no entanto, é considerado uma prática ruim usar uma interface apenas com métodos padrão.
fonte
você não pode fazer herança múltipla em java. considere usar interfaces:
ou classes internas:
fonte