Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

¿Simular herencia multiple?

195 views
Skip to first unread message

Fco Javier Pulido Vaquero

unread,
Nov 12, 1998, 3:00:00 AM11/12/98
to
¿Puedes aclararme un poco?

- ¿Cómo podría simular herencia múltiple en Java? Sé que se puede conseguir
implementando Interfaces en una clase, pero le he dado vueltas al asunto y
aún no lo tengo muy claro.

Un cordial saludo, ;-)

fjpu...@lobocom.es


Alejandro Navarro

unread,
Nov 12, 1998, 3:00:00 AM11/12/98
to

Crea una clase que implemente varias interfaces y dentro desarrolla los
métodos de las interfaces.

Ej.

class MiClase implements Interface1, Interface2, ...
{
void Metodo1Interface1
{
Tu código
}

void Metodo2Interface1
{
Tu código
}
.
.
.
void Metodo1Interface2
{
Tu código
}
.
.
.
}


Jonathan Revusky

unread,
Nov 12, 1998, 3:00:00 AM11/12/98
to

Fco Javier Pulido Vaquero wrote:
>
> ¿Puedes aclararme un poco?
>
> - ¿Cómo podría simular herencia múltiple en Java? Sé que se puede conseguir
> implementando Interfaces en una clase, pero le he dado vueltas al asunto y
> aún no lo tengo muy claro.
>

Un modo de simularlo es con las inner classes.

Digamos que tienes clases A y B y quieres que C tenga acceso a la
implementación protegida de A y B. Una cosa que se puede hacer es hacer
que C sea una subclase de A pero una inner class de B (o vice versa).

class A {

}

class B {
class C extends A {
// El código dentro de C puede invocar todos los métodos de A
// y de B, ya que está asociado con una instancia de clase B.
}
}

Espero que esto ayude.


Jonathan Revusky
--
Available for Java and Delphi Consulting
Make your .class files double-clickable
with SmartJ
http://www.bigfoot.com/~crystalline.solutions

Juan Gonzalo de Silva Medina

unread,
Nov 12, 1998, 3:00:00 AM11/12/98
to
Jonathan Revusky wrote:
>
> Fco Javier Pulido Vaquero wrote:
> >
> > - ¿Cómo podría simular herencia múltiple en Java?
> > [...]

>
> Un modo de simularlo es con las inner classes.
>
> Digamos que tienes clases A y B y quieres que C tenga acceso a la
> implementación protegida de A y B. Una cosa que se puede hacer es hacer
> que C sea una subclase de A pero una inner class de B (o vice versa).
>
> class A {
>
> }
>
> class B {
> class C extends A {
> // El código dentro de C puede invocar todos los métodos de A
> // y de B, ya que está asociado con una instancia de clase B.
> }
> }
>
> Espero que esto ayude.

Jonathan, no lo entiendo. Espero que no sean especificaciones de la 1.2
Yo he hecho:

----------------8<-----------------
class A{
private void mensajeA(){ System.out.println("Soy a"); }
}
class B{
private void mensajeB(){ System.out.println("Soy b"); }
class C extends A{
public void mensajes(){
mensajeA();
mensajeB();
}
}
}
class D{
public static void main(String s[]){
C c = new C();
c.mensajes();
}
}
----------------8<-----------------

Con lo que C extenderia A y B a la vez.

Como respuesta, al compilar obtengo:

prb.java:10: No method matching mensajeA() found in inner class B. C.
mensajeA();
^
prb.java:18: Class C not found in type declaration.
C c = new C();
^
prb.java:18: Class C not found in type declaration.
C c = new C();
^

Tengo claro que los dos ultimos errores son ciertos, ya que C no puede
ser instanciada ya que su ambito se restringe a la clase B.

Pero el primero de ellos parece que dice que C no "extiende" A.

Un poco raro ¿no?

--
Juan Gonzalo de Silva Medina
http://www.caymasa.es/usr/gonzalo
mail:gon...@caymasa.es
Powered by Red Hat 5.1 2.0.35 and Java

Jonathan Revusky

unread,
Nov 13, 1998, 3:00:00 AM11/13/98
to
Juan Gonzalo de Silva Medina wrote:
>
> Jonathan, no lo entiendo. Espero que no sean especificaciones de la 1.2

No, esto tiene que ver con el lenguaje y el lenguaje en sí no ha
cambiado entre 1.1 y 1.2. Muchos nuevos API's, pero el lenguaje es el
mismo.

> Yo he hecho:
>
> ----------------8<-----------------
> class A{
> private void mensajeA(){ System.out.println("Soy a"); }
> }

Tendría que ser algo como:

protected void mensajeA()

ya que incluso las subclases de A no pueden acceder a la implementación
"private". Tiene que ser "protected".

> class B{
> private void mensajeB(){ System.out.println("Soy b"); }
> class C extends A{
> public void mensajes(){
> mensajeA();
> mensajeB();
> }
> }
> }
> class D{
> public static void main(String s[]){
> C c = new C();
> c.mensajes();
> }
> }


La clase D no puede ser compilada porque no hay ninguna instancia de B a
la que la instancia de clase C puede ser asociada. (¿Eso es claro
acaso?)

De hecho, necesitarías algo como:

class B {
private void mensajeB() {...}
class C extends A {
....
}

C createC() {
return new C();
}
}

class D {
public static void main(String s[]){

B b = new B();
C c = b.createC();
c.mensajes();
}
}


> ----------------8<-----------------
>
> Con lo que C extenderia A y B a la vez.

No extiende A y B a la vez porque no hay herencia multiple en Java. Pero
es un modo de simularlo en cierto modo.


>
> Como respuesta, al compilar obtengo:
>
> prb.java:10: No method matching mensajeA() found in inner class B. C.
> mensajeA();
> ^
> prb.java:18: Class C not found in type declaration.
> C c = new C();
> ^
> prb.java:18: Class C not found in type declaration.
> C c = new C();
> ^
>
> Tengo claro que los dos ultimos errores son ciertos, ya que C no puede
> ser instanciada ya que su ambito se restringe a la clase B.

> Pero el primero de ellos parece que dice que C no "extiende" A.

El método tendría que ser "protected" por lo menos. "Private" es
realmente privado. No tiene acceso ni las subclases.


> Un poco raro ¿no?

Un poco rollo quizá... :-) Raro, no, porque, en realidad, todo está
funcionando como debe funcionar....

Un saludo,

Juan Gonzalo de Silva Medina

unread,
Nov 13, 1998, 3:00:00 AM11/13/98
to
Jonathan Revusky wrote:

>
> [...]


> Tendría que ser algo como:
>
> protected void mensajeA()
>
> ya que incluso las subclases de A no pueden acceder a la implementación
> "private". Tiene que ser "protected".

Vale, mala hora para probar...

>
> >[...]


> La clase D no puede ser compilada porque no hay ninguna instancia de B a
> la que la instancia de clase C puede ser asociada. (¿Eso es claro
> acaso?)

Ciertamente, no.

No entiendo lo que quieres decir por "asociada" ¿?.

>
> De hecho, necesitarías algo como:
>
> class B {
> private void mensajeB() {...}
> class C extends A {
> ....
> }
>
> C createC() {
> return new C();
> }
> }
>

> [...]


No me funciona, y sigo con lo mismo :-?, en la clase D no puede aparecer
ninguna referencia a la clase C ya que el compilador no puede encontrar
la definicion de la clase. Existe solamente dentro de la clase B.

> > Un poco raro ¿no?
>
> Un poco rollo quizá... :-) Raro, no, porque, en realidad, todo está
> funcionando como debe funcionar....
>

¿rollo? no creo, a mi me gusta urgar dentro, lo otro..., ya lo dice el
manual :-).

Saludos,

P.S.: Por la velocidad parece un chat ;-).

--

Juan Gonzalo de Silva Medina

Jonathan Revusky

unread,
Nov 13, 1998, 3:00:00 AM11/13/98
to
Juan Gonzalo de Silva Medina wrote:
>
> Jonathan Revusky wrote:
>
> >
> > [...]
> > Tendría que ser algo como:
> >
> > protected void mensajeA()
> >
> > ya que incluso las subclases de A no pueden acceder a la implementación
> > "private". Tiene que ser "protected".
>
> Vale, mala hora para probar...
>
> >
> > >[...]
> > La clase D no puede ser compilada porque no hay ninguna instancia de B a
> > la que la instancia de clase C puede ser asociada. (¿Eso es claro
> > acaso?)
>
> Ciertamente, no.

Bien. Gracias, por decírmelo. A veces, tengo la incómoda sensación de
que he contestado algo de modo un tanto críptico quizá, pero que no me
piden que lo explicite más porque tienen miedo de parecer tontos o algo
así.



> No entiendo lo que quieres decir por "asociada" ¿?.

A ver. En el contexto de una clase, (por lo menos si no estamos en un
método estático) siempre hay una referencia implícita a una instancia de
la clase.
Se trata del "this".

En el caso de una clase interior, en realidad hay dos referencias tipo
"this". Hay una referencia a la clase en sí y la clase que la contiene.
La inner class y la outer class. En el código en cuestión:

class B {
private void mensajeB() {...}
class C extends A {

mensajeA(); // Es equivalente a this.mensajeA();
mensajeB(); // Esto es equivalente a B.this.mensajeB();
}
}

Es decir que hay dos referencias "this". Si hay que explicitar el "this"
de la clase exterior, se utiliza la sintaxis: OuterClass.this.methode();

Si entiendes todo esto, creo que se ve bastante fácilmente porque en la
clase D, no puedes instanciar la inner class C sin tener una instancia
de B. Cuando dije que no había ninguna instancia de B a la que la clase
C podía ser asociada, es lo que quería decir.

class B {
private void mensajeB() {...}
class C extends A {
....
}

C createC() {
// aquí, sí que hay una instancia implícita de la
// outer class B así que funciona.
return new C();
}
}

>
> No me funciona, y sigo con lo mismo :-?, en la clase D no puede aparecer
> ninguna referencia a la clase C ya que el compilador no puede encontrar
> la definicion de la clase. Existe solamente dentro de la clase B.

Me equivoqué en el ejemplo, de hecho. Eso suele ocurrirnos a los
mortales cuando entramos código directamente en Netscape sin verificar
que se compila. :-)

public class D {


public static void main(String s[]){
B b = new B();

B.C c = b.createC();
//Había que explicitar B.C,
//aunque se podría haber puesto: import B.*;
//todo arriba y entonces se podría haber escrito simplemente:
// C c = b.createC();
c.mensajes();
}
}


> ¿rollo? no creo, a mi me gusta urgar dentro, lo otro..., ya lo dice el
> manual :-).
>
> Saludos,
>
> P.S.: Por la velocidad parece un chat ;-).

Ya no. :-)

De todas formas, agrego abajo el código ilustrativo. He verificado que
sí que se compila y funciona. Como dije, es un modo de "simular" la
herencia múltiple ya que la clase B.C puede acceder transparentement a
la implementación protegida de las clases A y B.

De hecho, todo esto es mucho mejor que la herencia múltiple de C++ por
una variedad de motivos...

Jonathan Revusky
--
Available for Java and Delphi Consulting
Make your .class files double-clickable
with SmartJ
http://www.bigfoot.com/~crystalline.solutions

-------------------------------------------------------------
// El fichero D.java que ilustra
// algunos puntos finos sobre las inner clases.

class A {
protected void mensajeA(){ System.out.println("Soy a"); }
}


class B {


private void mensajeB(){ System.out.println("Soy b"); }
class C extends A{
public void mensajes(){
mensajeA();
mensajeB();
}
}

C createC() {
return new C();
}
}

public class D {


public static void main(String s[]){
B b = new B();

B.C c = b.createC();
c.mensajes();
}
}

Juan Gonzalo de Silva Medina

unread,
Nov 15, 1998, 3:00:00 AM11/15/98
to
Jonathan Revusky wrote:

> [...]

Muchas gracias Jonathan ha sido de lo mas interesante.

Saludos,

--

Juan Gonzalo de Silva Medina

Fco Javier Pulido Vaquero

unread,
Nov 18, 1998, 3:00:00 AM11/18/98
to

Para simular la herencia multiple ¿podría ser más completo lo siguiente?

Ej.

class claseA implements InterfaceA
{ Implementar metodos de interfaceA, constructores, etc }

class claseB implements InterfaceB
{ Implementar metodos del interfaceB, constructores, etc }

class MiClase implements InterfaceA, InterfaceB
{
protected InterfaceA objA;
protected InterfaceB objB;
public MiClase


objA=(claseA) new InterfaceA;
objB=(claseB) new InterfaceB;
}

void Metodo1InterfaceA


// Tu código si quieres sobrecargar o
objA.Metodo1InterfaceA()
}
.
.
// Igual con el resto de métodos de InterfaceA

void Metodo1InterfaceB


// Tu código si quieres sobrecargar o
objB.Metodo1InterfaceB()
}
.
.
// Lo mismo con el resto de métodos del InterfaceB
}


Un cordial saludo ;-)

fjpu...@lobocom.es


0 new messages