Gostaria de saber a opinião do pessoal por aqui!
A herança deve ser evitada, dando enfase a composição. Sim ou Não?
Qual a opinião de vocês?
Gostaria de saber a opinião do pessoal por aqui!
A herança deve ser evitada, dando enfase a composição. Sim ou Não?
Qual a opinião de vocês?
Gostaria de saber a opinião do pessoal por aqui!A herança deve ser evitada, dando enfase a composição. Sim ou Não?
Qual a opinião de vocês?
E qual a sua opinião a respeito disso?
http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/
Effective Java, Joshua Bloch - item 14: ?prefira composição em vez de herança?
Gostaria de saber a opinião do pessoal por aqui!A herança deve ser evitada, dando enfase a composição. Sim ou Não?
Qual a opinião de vocês?
E qual a sua opinião a respeito disso?
Uso herança em casos muito particulares, pois na herança uma modificação em uma classe gerará reflexo para todas as outras na estrutura hierarquica… num sistema complexo, você possui muitos detalhes, logo, deverá ficar sobrecarregando métodos em classes para casos especificos! Dá mais trabalho…diante disso e de um monte problemas que passei…não uso herança com frequencia…prefiro a composição, acredito que dá mais enfase no objetivo que as classes possuem! Mas em alguns poucos casos uso a herança!!
Mas nem por isso, gostaria da opinião do pessoal do forúm, para ver se tomei atitude certa!! Sabe como é, duas cabeças pensam melhor que uma!!!
o bom de usar herança se puder fazer bom proveito de reflection pois assim da pra delegar para o pai fazer as ações… por exemplo um metodo salvar vc pode delegar a uma classe pai que tenha este salvar e usar reflection implementar a logica do salvar… todas as classes que herdarem desta que tem o salvar… vc não precisara implementar a logica deste metodo nestas classes…
em casos assim a herança e boa coisa…
o bom de usar herança se puder fazer bom proveito de reflection pois assim da pra delegar para o pai fazer as ações… por exemplo um metodo salvar vc pode delegar a uma classe pai que tenha este salvar e usar reflection implementar a logica do salvar… todas as classes que herdarem desta que tem o salvar… vc não precisara implementar a logica deste metodo nestas classes…
em casos assim a herança e boa coisa…
a) O que a herança tem a ver com reflection? São coisas completamente distintas. C++ não tem reflection (pelo menos algo que seja simples de usar) mas nem por isso deixa de usar herança (talvez até desnecessariamente).
b) O problema da herança é que a principal motivação para seu uso (que você está citando) é o reaproveitamento de código. Nada contra; só que o problema é que o reaproveitamento de código também gera muitos problemas, que foram citados pelo artigo do Paulo Silveira que consta no blog que citei acima.
o bom de usar herança se puder fazer bom proveito de reflection pois assim da pra delegar para o pai fazer as ações… por exemplo um metodo salvar vc pode delegar a uma classe pai que tenha este salvar e usar reflection implementar a logica do salvar… todas as classes que herdarem desta que tem o salvar… vc não precisara implementar a logica deste metodo nestas classes…
em casos assim a herança e boa coisa…a) O que a herança tem a ver com reflection? São coisas completamente distintas. C++ não tem reflection (pelo menos algo que seja simples de usar) mas nem por isso deixa de usar herança (talvez até desnecessariamente).
b) O problema da herança é que a principal motivação para seu uso (que você está citando) é o reaproveitamento de código. Nada contra; só que o problema é que o reaproveitamento de código também gera muitos problemas, que foram citados pelo artigo do Paulo Silveira que consta no blog que citei acima.
Herabça não tem nada haver com reflection… so estou citando um dos casos que pode ser usado como algo que pode dar muita vantagem… e apenas um exemplo de inumeros que eu citei…
Ja que vc citou o C++… C++ tem o mecanismo de herança multipla… o que gera o tal problema do diamante… algo que eu nunca soube e como resolver este problema do diamante sem terque evitalo… como se resolve isto?
Ja que vc citou o C++… C++ tem o mecanismo de herança multipla… o que gera o tal problema do diamante… algo que eu nunca soube e como resolver este problema do diamante sem terque evitalo… como se resolve isto?
Atraves do uso de interfaces + composicao :). Citando C++, entao vale falar do livro Design Patterns. Um dos dois principios la citado é “Evite heranca, favoreca composicao”. E la ele fala para usar interfaces. Vale lembrar que na epoca que eles escreveram o livro, nao existia Java, e “interface” era apenas um conceito, e como a maioria dos exemplos sao em C++, ele usa varias classes abstratas, e faz heranca multipla pra elas, sem que elas tenham nada de implementacao. (creio eu que Java foi a primeira linguagem a ter uma palavra chave para classes abstratas que nao possuem nada de concreto: interface).
O problema do “diamante” foi “resolvido” em Eiffel mas de uma forma meio “gambiarresca” embora intuitiva. Eiffel usa herança múltipla mas se for detectado o tal problema do diamante você tem de explicitar a partir de qual classe você quer herdar o determinado método.
Em C++ o problema ocorre e dá erros de compilação:
#include <iostream>
using namespace std;
// Herança múltipla clássica
class A {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class B {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class C: public A, public B {
};
// Herança múltipla à la Java, com interfaces
// (Chamadas em C++ de "funções virtuais puras").
class X {
public:
virtual void a() = 0;
virtual void b() = 0;
};
class Y {
public:
virtual void b() = 0;
virtual void c() = 0;
};
class Z : public X, public Y {
public:
virtual void a() { cout << __FUNCTION__ << endl; }
virtual void b() { cout << __FUNCTION__ << endl; }
virtual void c() { cout << __FUNCTION__ << endl; }
};
int main (int argc, char*argv[]) {
Z* z = new Z();
z->b(); // mostra Z::b
X* x = z;
x->b(); // mostra Z::b
Y* y = z;
y->b(); // mostra Z::b
C c;
// Se descomentarmos a linha seguinte:
// c.b();
// Teremos o seguinte erro de compilação:
// HerancaMultipla.cpp(19) : error C2385: ambiguous access of 'b'
// could be the 'b' in base 'A'
// or could be the 'b' in base 'B'
// HerancaMultipla.cpp(19) : error C3861: 'b': identifier not found
}
thingol
e se a classe C so herdasse de A, mas a classe D herdasse de C e de outra classe X que tambem tem o metodo b, e eu fizesse uma invocacao virtual:
C &c = new D();
c.b();
ele nao enxergaria, certo? Como fica a execucao?
De fato, Paulo, é um bocadinho chato de entender o que se passa. Ele pega o “b” de acordo com o caminho da herança que ele considera mais razoável.
#include <iostream>
using namespace std;
// Herança múltipla clássica
// O mecanismo de resolução de herança no C++ é um pouco
// confuso e não muito intuitivo. Evite fazer tal tipo
// de coisas, para evitar choro e ranger de dentes.
//
class A {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class B {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class X {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class C: public A {
public:
virtual void b () { cout << __FUNCTION__ << endl; }
};
class D: public C, public X {
//public:
// virtual void b () { cout << __FUNCTION__ << endl; }
};
int main (int argc, char*argv[]) {
C* c = new D();
A* a = c;
c->b(); // imprime "c::b"
a->b(); // imprime "c::b"
// se descomentarmos a implementação de b na classe D, imprime "d::b"
X* x = new D();
x->b(); // imprime "x::b"
// se descomentarmos a implementação de b na classe D, imprime "d::b"
}
valeu google-melhorado-em-forma-de-humano
digo, thingol