Herança Multipla

41 respostas
A

Olá pessoal.

Continuando a serie de topicos do tipo “Por que java não XXX” http://www.guj.com.br/posts/list/65469.java#344793

agora é a vez de herança multipla.

Por que naum por herança multipla no java… tipo do que eles tem medo que saiam anomalias dos sistemas…
Não é errado isto da linguagem presumir que voce é um idiota então proibir tudo que possa causar confusão.

Afinal em nenhuma hipotese seria util modelar algo com herança multipla…

Gostaria da opnião de voces…

Grato.

41 Respostas

sergiotaborda

AndrewAguiar:
Olá pessoal.

Continuando a serie de topicos do tipo “Por que java não XXX” http://www.guj.com.br/posts/list/65469.java#344793

agora é a vez de herança multipla.

Por que naum por herança multipla no java… tipo do que eles tem medo que saiam anomalias dos sistemas…
Não é errado isto da linguagem presumir que voce é um idiota então proibir tudo que possa causar confusão.

Afinal em nenhuma hipotese seria util modelar algo com herança multipla…

Gostaria da opnião de voces…

Grato.

Lei de Murphy: Tudo o que poder dar errado, vai dar errado.
Se vc libera a HM algo vai dar errado. Isso foi provado com C++ ( assim como manipular ponteiros directamente) e foi removido em Java. Java sim é um linguagem que defende melhores formas de programação
e portanto elimina tudo o que pode causar anomalias. Não necessáriamente presume que o programador é idiota.Ela presume que o programador comete erros , e certos erros são idiotas. Por exemplo, a palavra chave “goto” é reservada em Java exatamente para que não seja usada.

P

Como não encontrei nada que não pude fazer em Java por falta de herança múltipla, não me atrapalha o fato de não tê-la.

Talvez algumas coisas até fosse facilitadas com ela, mas tudo que encontrei foi possível de ser resolvido de outra maneira.

A

Mais no caso da herança multipla não tem como cometer erros… ou o cara modela com HM ou não. Penso q isso de “evitar que o programador se confunda”, apenas tira flexibilidade.

sergiotaborda

como vc mesmo disse " Afinal em nenhuma hipotese seria util modelar algo com herança multipla… "
Então, se não vou usar, para quê colocar ?

Lembre-se que herança nem sempre serve para modelar, às vezes serve so para reaproveitar codigo.
Como java isa HM simples, modelar implica em reaproveitar codigo e vice-versa. Já com HM nem sempre um implica o outro e ai que são criados os problemas.

peczenyj

Alguem acredita realmente que o fato do java não suportar herança multipla tem haver com tornar os programas mais seguros?

Me parece ser uma questão de design.

Agora se uma classe pode extender uma outra classe e implementar diversas interfaces, não vejo motivo para não poder extender muitas classes (Só não consigo entender como o super() iria funcionar nesse caso, a menos que haja apenas uma classe “principal”, enfim…).

A

como vc mesmo disse " Afinal em nenhuma hipotese seria util modelar algo com herança multipla… "

Escrevi errado:

Isso eh uma pergunta… esqueci o “?”

Não entendi ? A HM tem a função de reaproveitar codigo também pelo que eu saiba.

A

Voce poderia qualificar o super… que nem em python.

public void fazAlgo(int codigo){
       ClasseMae.super.fazAlgo(codigo);
       ClasseMaeAdotiva.super.fazAlgo(codigo);
}

dai tipo para manter a compatibilidade poderia ter a seguinte regra, se não tiver qualificado, então considera da primeira classe após a clausula extends…

P

O que vocÊ precisou fazer em Java e não conseguiu por falta de herança múltipla ?

A

Consegui eu consegui com interfaces só acho que em determinados casos seria mais facil fazer com HM.

sergiotaborda

Sim, mas não ao mesmo tempo a de modelar. A regra “É-UM” pode ser facilmente quebrada
Imagina class A extends B , Helper onde Helper tem um mote de codigo utilitário

A não é um Helper do ponto da modelagem, eu so estendi Helper para aproveitar o codigo.

Em java era comum usar constantes em interfaces e herdar as interfaces para ter acesso às constantes (SwingConstants, por exemplo).Isso é errado pelo mesmo motivo. A interface desempenhava o papel de utilitário de reaproveitamento de codigo sem respeitar a regra “É-UM”. Por isso vieram os Enum, e por isso este tipo de coisa é um anti-pattern. Portanto, HM não teria qualquer utilidade prática. Só criaria problemas e paradoxos.

Um das coisas que acho melhores no Java é a sua sintaxe simples e a sua politica de fazer muito com pouco. Herança simples é poderosa o suficiente, não precisa sequer existir um herança multipla. Claro, não precisa existir HM porque termos interfaces, entenda-se.

P

Sim, em alguns casos a HM seria útil, da mesma forma que citaram ai acima, que em alguns casos a HM permitiria que fossem feitas coisas que não deveriam ser feitas.

Eu acho que é questão de se adaptar ao que se tem disponível.

A

paulohrl :
Sim, mas não ao mesmo tempo a de modelar. A regra “É-UM” pode ser facilmente quebrada
Imagina class A extends B , Helper onde Helper tem um mote de codigo utilitário

A não é um Helper do ponto da modelagem, eu so estendi Helper para aproveitar o codigo.

Sim neste caso é gambi… mais na modelagem algumas vezes encontramos classes que tem esta caracteristica:

class Helicoptero extends Transporte, Ativo

Assim posso tanto me referir ao Helicoptero como um Transporte e um Ativo claro que isto é perfeitamente possivel com o uso de interface mas imagine que para cada veiculo que eu tivesse eu teria que implementar coisas referentes a interface Ativo

public interface Ativo
{
     double getValor();

     int getTempoDepreciacao();
}

public class Transporte
{
	// Varios metodos.
}

public class Helicoptero extends Transporte implements Ativo
{
	// Metodos proprios
	private double valor;
	private int tempoDepreciacao;
	
	public double getValor(){
		return valor;
	}
	
	public int getTempoDepreciacao(){
		return tempoDepreciacao;
	}
}

public class Yate extends Transporte implements Ativo
{
	// Metodos proprios
	
	private double valor;
	private int tempoDepreciacao;
	
	public double getValor(){
		return valor;
	}
	
	public int getTempoDepreciacao(){
		return tempoDepreciacao;
	}
}

public class CarroParticular extends Transporte implements Ativo
{
	// Metodos proprios
	
	private double valor;
	private int tempoDepreciacao;
	
	public double getValor(){
		return valor;
	}
	
	public int getTempoDepreciacao(){
		return tempoDepreciacao;
	}
}

para cada classe tive que criar um metodo getValor() e getTempoDepreciacao(), e criar duas variaveis de instancia.

Já com HM ficaria:

class Ativo
{
	private double valor;
	private int tempoDepreciacao;
	
	public double getValor(){
		return valor;
	}
	
	public int getTempoDepreciacao(){
		return tempoDepreciacao;
	}
}

class Transporte
{
	// Varios metodos.
}

class Helicoptero extends Transporte, Ativo
{
	// Metodos proprios
}

class Yate extends Transporte, Ativo
{
	// Metodos proprios
}

class CarroParticular extends Transporte, Ativo
{
	// Metodos proprios
}

O que é do Ativo fica na classe ativo. bem mais simples e não duplica código.

P

Concordo com você que facilitaria em alguns casos. O que estou dizendo é que é possível fazer qualquer coisa sem utilizar a HM.

A

Mais só porque é possivel não quer dizer que seja a melhor maneira. da pra fazer qualquer laço de repetição em pascal usando apenas if e goto mais nem por isso retiraram os fors e whiles.

Isso cai no que eu tinha falado, parece que a linguagem presume que o programador é idiota. e que para evitar dele cometer erros tiram recursos que possam ser uteis mas que consideram dificeis. :wink:

sergiotaborda

Esse exemplo do ativo não é o melhor para demostrar a necessidade de HM porque começa com um erro de modelagem. Um Transporte não é um ativo (Violação do É-UM). Aliás , pode ser um Passivo :lol:

VC está querendo reaproveitar codigo…

O que eu quero dizer é que “Ativo” é um papel que Transporte desempenha num contexto (Contábil). Isso não é modelável com “É-UM” (É o mesmo problema de pessoa fisica e juridica) Teria que ser assim :

Transporte t = ...
Activo act = Activo.ativoPara(t);

Eu entendi o que vc quiz dizer, mas duvido que usar HM seja sinônimo de boa modelagem.

A

Em nenhum momento eu disse que Transporte é um ativo.

public class Transporte
{
}

Helicoptero, Carro e Yate são Ativos.

sergiotaborda

Em nenhum momento eu disse que Transporte é um ativo.

public class Transporte
{
}

Helicoptero, Carro e Yate são Ativos.

Ok, mas o argumento se mantem. Só trocar “transporte” por qualquer um dos transportes reais.

leandros

Motivo de Java não ter herança múltipla é por causa do efeito Diamante que pode acontecer no Design.

L

AndrewAguiar mostrou um exemplo bastante interessante sobre herança múltipla. Mas eu poderia mostrar esse mesmo exemplo, sem utilizar herança múltipla e, ao mesmo tempo, sem replicação de código. Veja:

A interface Ativo e a classe Transporte seriam as mesmas.

public interface Ativo
{
     double getValor();

     int getTempoDepreciacao();
}

public class Transporte
{
	// Varios metodos.
}

Agora eu teria a classe AtivoImpl, que implementa Ativo:

public class AtivoImpl implements Ativo
{
	private double valor;
	private int tempoDepreciacao;

	public double getValor(){
		return valor;
	}
	
	public int getTempoDepreciacao(){
		return tempoDepreciacao;
	}
}

E aí, as classes que herdam de Transporte (não todas) teriam uma instância de Ativo:

public class Helicoptero extends Transporte
{
	// Metodos proprios

	private Ativo ativo = new AtivoImpl();

	public Ativo getAtivo(){
		return ativo;
	}
}
public class Yate extends Transporte
{
	// Metodos proprios

	private Ativo ativo = new AtivoImpl();

	public Ativo getAtivo(){
		return ativo;
	}
}

public class CarroParticular extends Transporte
{
	// Metodos proprios

	private Ativo ativo = new AtivoImpl();

	public Ativo getAtivo(){
		return ativo;
	}
}

E aí, sempre que o cliente precisar de saber algo do transporte como ativo, basta fazer:

CarroParticular cp = new CarroParticular();
// um monte de regras...
Ativo ativoCarroParticular = cp.getAtivo();
double valor = ativoCarroParticular.getValor();

Tudo bem, não é tão bonito se tivesse herança múltipla, mas ela resolve o problema de não se repetir código, ao mesmo tempo fazendo uso apenas de herança simples. E isso pode ser feito em qualquer situação onde a modelagem pede a herança múltipla, basta pegar o “elo mais fraco”, no nosso caso a inteface Ativo, e transformá-la em um relacionamento TEM-UM.

L

Um outro problema da herança múltipla é o efeito diamante que, se não for bem pensado, pode gerar um pepino bem grande pro desenvolvedor. Imaginemos que Java possua herança múltipla, e que tivéssemos as classes Tranporte e Ativo estendendo diretamente Object. Então, estenderiamos tanto Transporte e Ativo para a criação da classe Yate, porém sem o método equals.

Bom, chega um certo momento que uma referência Object possua uma instancia Yate, assim:

Object obj = yate;

Aí, numa outra parte do código, quero chamar equals()

obj.equals(anotherObj);

Pergunta: o que que o interpretador java irá fazer? Não pode chamar equals de Yate, pq não tem. Tanto Transporte quanto Ativo possuem o mesmo nível de hierarquia, e não daria pra chamar um antes do outro ou escolher um deles pois não existe nada codificado dizendo isso. E não dá pra seguir tipo uma “convenção sobre configuração” dizendo que a primeira classe após a palavra extends é a que vale, porque geraria muita confusão pros novatos que veriam um programa não-responsivo.

Bom, poderíamos criar o método equals na classe Yate, então! Mas se precisarmos chamar o super, quem seria a referência? O C++ tem o operador de escopo (::slight_smile: onde basta escolher qual superclasse se quer utilizar, mas isso só acontece porque C++ possui um modelo de gerenciamento memória bastante diferente do Java, o qual dá pra fazer isso. Em Java, nem pensar.

Uma outra situação, e se Transporte e Ativo não estendessem Object, mas ObjectPlus, cuja implementação é essa?

public class ObjectPlus {
    
    int quantidade;

    public int getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
    }
    
}

Imagine: Transporte tem a sua variável quantidade, Ativo também, e Yate? Sendo herdeiro de duas classes, não teria duas variáveis “quantidade”? E quando eu chamo:

ObjectPlus objPlus = yate;
objPlus.setQuantidade(3);

De que implementação eu estou considerando? Transporte ou Ativo?

Por essas coisas, é que é bem melhor usar herança simples, não dá tanta dor de cabeça. Até mesmo quando eu programava em C++, só usava herança simples. Na única vez que tentei, deu um monte de pau, e como as mensagens de erro não são lá muito claras, resolvi nem seguir adiante.

peczenyj

HM é confusa mas C++ e Python tem :wink:

pcalcado

Todos os problemas citados com herança múltipla são resolvidos em Eiffel, C++, Python ou na teoria de tipos. java não tem herança múltipla por design. De qualquer forma as pessoas ainda não conseguiram depois de 40 anos entender herança simples, imagine múltipla. Eu sou cada vez mais favorável à linguagens de escopo reduzido e DSLs.

ViniGodoy

Eu sinceramente acho que o Java faz bem em evitar recursos que podem causar dores de cabeças, imaginando que o programador é descuidado.

A história tem mostrado que isso é o que ocorre. Veja o caso do C++. O programador é obrigado a se lembrar de dar delete nos seus ponteiros. E isso geralmente não acontece. Os programadores de C++, usando os recursos de templates, inventaram os Smart Pointers. Um recurso específico para se proteger de si mesmos, do próprio esquecimento (ok, há outras razões, mas essa é a mais alegada).

Além disso, se você pegar livros como Effective C++ ou C++ for Game Programmers, vai ver que eles são unânimes em dizer para você não usar a herança múltipla, exceto no caso de Abstract Base Classes. E o que são Abstract Base Classes? Um conceito muito próximo das interfaces do java. Classes 100% abstrata, sem propriedades e sem métodos.

Finalmente, o tempo tem mostrado que hierarquias de classes curtas, com mais acoplamento do que herança, são mais sólidas que grandes cadeias de herança.

Eu sou um programador C++ a bastante tempo. Adoro a linguagem. Mas, o C++ exige que você seja um programador atento o tempo todo. Chega a ser uma certa paranóia. E isso é ruim, muito ruim. Programar em Java é um prazer, porque diversos fatores de stress foram removidos. E isso é bom, muito bom.

pcalcado

ViniGodoy:
Eu sinceramente acho que o Java faz bem em evitar recursos que podem causar dores de cabeças, imaginando que o programador é descuidado.

Eu concordo e acho pouco. As nvoas linguagens devem limitar o programador normal muito mais e focá-lo no negócio.

O problema é que C++ e Java são system languages que acabam virando kitchen sink languages, ou sacos de funcionalidades.

Ahm… não.

Interfaces são contratos. Uma interface não cria o relacionamento que existe entre uma classe e sua superclasse como obediência á Liskov Substitution Principle, uma classe abstrata sim. interfaces são recursos para garantir que classes possuam uma “interface” (uma API) comum.

Acho qeu você quis dizer composição e não acomplamento, certo? De qualquer modo, herança múltipla não implica emg randes hierarquias ou vice-versa.

A

Leonardo3001 :
AndrewAguiar mostrou um exemplo bastante interessante sobre herança múltipla. Mas eu poderia mostrar esse mesmo exemplo, sem utilizar herança múltipla e, ao mesmo tempo, sem replicação de código. Veja:

A interface Ativo e a classe Transporte seriam as mesmas.

Sem duplicação.

Voce esta colocando uma instancia de Ativo em cada classe e ainda por cima não é correto dizer que Um Helicoptero tem um ativo, e sim que é um ativo da empresa…

com HM voce só precisaria herdar de AtivoImp e pronto…

e ainda por cima deste modo voce não consegue se referir ao Helicoptero, Yate e Carro como sendo um ativo…

J2Alex

Helicoptero, Carro e Yate serão SEMPRE Ativos? Tem certeza disso? Pense um pouco.

Há sim um erro de modelagem no exemplo que você passou.

Em muitos casos é interessante evitar até mesmo a herança simples, que dirá herança múltipla. Não consegui contemplar até hoje um cenário real em que a herança múltipla fosse realmente necessária e não pudesse ser implementada de uma melhor forma utilizando interfaces ou strategy ou quaisquer outras soluções cabíveis ao contexto.

Definitivamente Helicoptero não é um ativo, ele pode ser um ativo em um dado momento, e só.

David

Isso me lembra uma frase que vi há algum tempo… não me lembro o autor:

A

Dependendo da modelagem sim.

Não ha erro algum na modelagem, e o fato de ele poder ser um ativo em determinada ocasião torna ele um ativo.
Se for assim a classe String não precisaria implementar CharSequence pois nem sempre voce esta lidando com uma CharSequence. na maioria das vezes voce so quer manipular uma String.

Sim voce consegue simular HM com interfaces mais estas são meras gambis, o fato é que voce tera que implementar comportamentos comuns para varias classes sendo que poderia ser implementado na classe.

ViniGodoy

Eu pensei em responder algo assim. Mas não concordo.

O compilador C++ fez uma solução simplista para o problema, mas o Java poderia partir para algo mais inteligente.

Para quem não sabe do problema, conside as classes:
Veiculo
Naval extends Veiculo
Terrestre extends Veiculo
Anfibio extends Terrestre, Naval

A classe veículo é pai de Anfíbio 2 vezes, uma delas através de Naval e outra através de Terrestre. No C++ isso é um problema, pois o compilador gerará efetivamente duas cópias da classe veículo.

O que acho que deveria acontecer, e é o que parece lógico, é que veículo não se duplicasse. Afinal, veículo é apenas uma classe.

Outro problema da herança múltipla, e aí sim, é um problema sério é o conflito de nomes. Ainda naquele diagrama. Considere que tanto a classe Naval quanto Terrestre tem um método com o mesmo nome, digamos, getMotor(). Entretanto, esse método é radicalmente diferente nas duas implementações. A grande questão é… o que fazer com ele?

Com interfaces, isso não é um problema, pois interfaces não tem implementações. Uma coisa que o java poderia fazer é impedir herança quando isso acontecesse. Ou limitasse isso para quando as classes implementassem uma interface comum e ainda obrigasse o programador a implementar alguma coisa no método conflitante. Acharam complicado?

Agora, o que fazer com campos protected conflitantes? Shadowing de um deles? Eliminar um dos campos? Impedir?

Em resumo, herança múltipla é um recurso complexo e de benefício muito questionável. Geralmente complica o design e quase sempre pode ser evitado. Então, para que ter isso na linguagem? Para agradar 10% dos programadores? Mas será que isso é justificativa para complicar a vida dos outros 90%?

ViniGodoy

Eu pensei em responder algo assim. Mas não concordo.

O compilador C++ fez uma solução simplista para o problema, mas o Java poderia partir para algo mais inteligente.

Para quem não sabe do problema, conside as classes:
Veiculo
Naval extends Veiculo
Terrestre extends Veiculo
Anfibio extends Terrestre, Naval

A classe veículo é pai de Anfíbio 2 vezes, uma delas através de Naval e outra através de Terrestre. No C++ isso é um problema, pois o compilador gerará efetivamente duas cópias da classe veículo.

O que acho que deveria acontecer, e é o que parece lógico, é que veículo não se duplicasse. Afinal, veículo é apenas uma classe.

Outro problema da herança múltipla, e aí sim, é um problema sério é o conflito de nomes. Ainda naquele diagrama. Considere que tanto a classe Naval quanto Terrestre tem um método com o mesmo nome, digamos, getMotor(). Entretanto, esse método é radicalmente diferente nas duas implementações. A grande questão é… o que fazer com ele?

Com interfaces, isso não é um problema, pois interfaces não tem implementações. Uma coisa que o java poderia fazer é impedir herança quando isso acontecesse. Ou limitasse isso para quando as classes implementassem uma interface comum e ainda obrigasse o programador a implementar alguma coisa no método conflitante. Acharam complicado?

Agora, o que fazer com campos protected conflitantes? Shadowing de um deles? Eliminar um dos campos? Impedir?

Em resumo, herança múltipla é um recurso complexo e de benefício muito questionável. Geralmente complica o design e quase sempre pode ser evitado. Então, para que ter isso na linguagem? Para agradar 10% dos programadores? Mas será que isso é justificativa para complicar a vida dos outros 90%?

ViniGodoy

pcalcado:
Ahm… não.

Interfaces são contratos. Uma interface não cria o relacionamento que existe entre uma classe e sua superclasse como obediência á Liskov Substitution Principle, uma classe abstrata sim. interfaces são recursos para garantir que classes possuam uma “interface” (uma API) comum.

Sim… sim… aqui estou usando o termo “Abstract Base Class” (ABCs) do mundo C++. Não confundir simplesmente com “Classe abstrata” do java. Eles são bem enfáticos em dizer que devem só conter métodos virtuais puros (ou seja, sem implementação), para que exprimam somente a funcionalidade exprimida pela ABC (em resumo, um contrato). Além do mais, quando se trata de uma herança múltipla com duas ABCs puras, o C++ não recai no problema do Diamond-of-Death. Existe código no compilador específico para isso. Aliás, sobre isso, recomendo a entrevista com o próprio autor do Effective C++:
http://www.artima.com/intv/abcs.html

Mas concordo, não é um conceito idêntico. E sempre há o risco de alguém começar a colocar código na ABC, quebrando todo conceito da arquitetura.

É, foi o que eu quis dizer. :slight_smile:

Realmente, herança múltipla não implica em grandes hierarquias. Mas as favorece. Especialmente o que se faz com “mixing classes”, que são classes de utilidade pequena, desenhadas justamente para se misturarem a outras. E as mixing classes estão sujeitas a todos os problemas da herança múltipla, inclusive os conflitos de nomes que citei ali em cima.

J2Alex

Talvez eu não tenha sido claro, mas o que eu quis dizer é que ele pode fazer parte do ativo num determinado momento, mas isso não o torna um ativo. O ativo possui um helicóptero, o relacionamento TEM UM é mais correto, mais coerente. Continuo achando que há erro na modelagem.

Ou a idéia é usar herança simplesmente para digitar menos código? Essa não é a melhor forma de se usar herança.

Quanto a comportamentos comuns você pode separá-los usando strategy.

Ah… e o exemplo da interface CharSequence foi infeliz, uma String não é nada mais que uma sequência de caracteres, então pode ser tratado dessa forma sem problemas.

F

Duvida…e na hora que o Helicoptero não tiver mais serventia e virar um Passivo o que fazer?

]['s

A

É o exemplo do Ativo e do Helicoptero não foi dos melhores, não tinha pensado nisto.

pcalcado

Sobre Diamanete, isso é estupidamente simples de resolver com linguagens estaticamente tipadas: Exija do programador que informe qual implementação ele quer se não sobrescrever o método.

ViniGodoy

Eu não simplificaria tanto assim. Há situações em que ambos os métodos são importantes.

E há as situações em que existem atributos protected (seja através de um getter protected ou de acesso direto), que devem ser modificados. Nesse caso, o que fazer? A alternativa C++ é indicar o caminho completo até o atributo.

Seja o que for… não vai ficar uma solução das mais elegantes e certamente vai rebuscar a hierarquia. Para não falar na legibilidade do código.

E tudo isso, para um recurso cujo real benefício é muito duvidoso, mas que a grande quantidade de problemas é bastante conhecida…

Luca

Olá

Ponto para você!

Sem querer me meter muito nesta discussão só vou dar um depoimento porque assisti ao nascimento do Java e me lembro bem dos argumentos que usavam para não ter herança múltipla.

Um deles e geralmente o primeiro citado, é justamente este. No livro The Java Programming Language do Ken Arnold e James Gosling da série The Java Series From The Source de 1996, no item 4.2 Single Inheritance versus Multiple Inheritance, logo no segundo parágrafo, depois de definir herança múltipla, aparece a tal figurinha do diamante onde W é super classe de X e Y e Z herda de X e de Y ao mesmo tempo. Em seguida a figura está o texto abaixo:

4.2 Single Inheritance versus Multiple Inheritance de The Java Programming Language:

This is commonly called “diamond inheritance”, and there is nothing wrong with it. Many legitimate designs show this structure. The problems exist in the inheritance of implementation, when W’s implementation stores some state. If class W had, for example, a public field named goggin, and if you had a reference to an object of type Z called zref, what would zref.goggin refer to? It might refer to X’s copy of goggin, or it might refer to Y’s copy, or X and Y might share a single copy of goggin because Z is really only a W once even though it is both an X and a Y.

Java uses the single-inheritance model of object-oriented programming to avoid such issues.

Single inheritance precludes some useful and correct designs. The problems of multiple inheritance arise from multiple inheritance of implementation, so Java provides a way to inherit a contract without inheriting implementation. The way is to declare as interface type, instead of a class type.

Isto é história, não é especulação.

[]s
Luca

pcalcado

Por isso que falei que quando não for sobrescrito deve decidir qual implementação utilizar. Veja o que Bertrand Meyer diz a respeito:

Simples.

pcalcado

Acho que quase todo mundo já tinha lido esta desculpa do Gosling, Luca, o ponto é que ela é esfarrapada. Dá pra resolver o problema de maneira muito simples e o argumento contra herança multipla contraria boa parte da teoria de OOP, a questão é que balanceando a solução com os benefícios de heranca multipla provavelmente acharam que nao vale a pena.

ViniGodoy

pcalcado:

Acho que quase todo mundo já tinha lido esta desculpa do Gosling, Luca, o ponto é que ela é esfarrapada. Dá pra resolver o problema de maneira muito simples e o argumento contra herança multipla contraria boa parte da teoria de OOP, a questão é que balanceando a solução com os benefícios de heranca multipla provavelmente acharam que nao vale a pena.

Taí, concordo em gênero, número e grau.

pcalcado

ViniGodoy:

Taí, concordo em gênero, número e grau.

Complementando: nao sei se estao certos ou nao. Java tende a se tornar uma kitchen sink language e ai isso faz falta mas nos ultimos dez anos nao tem feito. Talvez seja mais uma coisa a atrapalhar a evoluçao, nao sei.

Criado 5 de setembro de 2007
Ultima resposta 6 de set. de 2007
Respostas 41
Participantes 12