2012-06-21 54 views
7

Duplicar posible:
Multiple Inheritance in C#heredan de dos clases en C#

que tienen dos clases de Clase A y Clase B. Estas dos clases no pueden heredar el uno al otro. Estoy creando una nueva clase llamada Clase C. Ahora, quiero implementar los métodos en clase A y clase B heredando. Soy consciente de que la herencia múltiple no es posible en C#, pero ¿hay alguna otra forma de hacerlo?

Gracias

+0

Probablemente debería disponer de una interfaz ... http://stackoverflow.com/questions/178333/multiple-inheritance-in-c-sharp – Oofpez

+0

Buena Q Satish: p – Jacooobley

Respuesta

27

La herencia de múltiples niveles no es posible en C#, sin embargo, se puede simular mediante interfaces, consulte Simulated Multiple Inheritance Pattern for C#.

La idea básica es definir una interfaz para los miembros de la clase B que desea acceder (llámese IB), y luego tener C Heredar del A e implementar IB almacenando internamente una instancia de B, por ejemplo:

class C : A, IB 
{ 
    private B _b = new B(); 

    // IB members 
    public void SomeMethod() 
    { 
     _b.SomeMethod(); 
    } 
} 

También hay un par de otros patrones alternativos explicados en esa página.

3

Se puede definir una clase base para A y B donde se puede celebrar una comunes métodos/propiedades/campos de aquellos.

Después de implementar C:Base.

O con el fin de simular la herencia múltiple, definen un común interface (s) y ponerlas en práctica en C

Espero que esto ayude.

+0

Si i uso de la interfaz, entonces necesito definir los métodos en la Clase C. ¿Hay alguna otra forma en que pueda llamar directamente a los métodos? – Virus

+0

@Virus: no es necesario que defina los ** métodos **, sino solo aquellos que desee * compartir * entre diferentes tipos. – Tigran

7

Una alternativa común a la herencia es delegación (también llamada composición): X "tiene una" Y en vez de X "es una" Y. Entonces, si A tiene funcionalidad para tratar con Foos, y B tiene funcionalidad para tratar bares, y desea que tanto en C, entonces algo como esto:

public class A() { 
    private FooManager fooManager = new FooManager(); // (or inject, if you have IoC) 

    public void handleFoo(Foo foo) { 
    fooManager.handleFoo(foo); 
    } 
} 

public class B() { 
    private BarManager barManager = new BarManager(); // (or inject, if you have IoC) 

    public void handleBar(Bar bar) { 
    barManager.handleBar(bar); 
    } 
} 

public class C() { 
    private FooManager fooManager = new FooManager(); // (or inject, if you have IoC) 
    private BarManager barManager = new BarManager(); // (or inject, if you have IoC) 

    ... etc 
} 
2

uso composition:

class ClassC 
{ 
    public ClassA A { get; set; } 
    public ClassB B { get; set; } 

    public C (ClassA a, ClassB b) 
    { 
     this.A = a; 
     this.B = b; 
    } 
} 

a continuación, puede llamar C.A.DoA(). También puede cambiar las propiedades a una interfaz o clase abstracta, como public InterfaceA A o public AbstractClassA A.

6

Si desea utilizar literalmente el código de método de A y B, puede hacer que su clase C contenga una instancia de cada uno. Si codifica contra interfaces para A y B, entonces sus clientes no necesitan saber que les está dando un C en lugar de un A o un B.

interface IA { void SomeMethodOnA(); } 
interface IB { void SomeMethodOnB(); } 
class A : IA { void SomeMethodOnA() { /* do something */ } } 
class B : IB { void SomeMethodOnB() { /* do something */ } } 
class C : IA, IB 
{ 
    private IA a = new A(); 
    private IB b = new B(); 
    void SomeMethodOnA() { a.SomeMethodOnA(); } 
    void SomeMethodOnB() { b.SomeMethodOnB(); } 
} 
3

Hacer dos interfaces IA y IB:

public interface IA 
{ 
    public void methodA(int value); 
} 

public interface IB 
{ 
    public void methodB(int value); 
} 

Siguiente hacen A implemento IA y B implemento IB.

public class A : IA 
{ 
    public int fooA { get; set; } 
    public void methodA(int value) { fooA = value; } 
} 

public class B : IB 
{ 
    public int fooB { get; set; } 
    public void methodB(int value) { fooB = value; } 
} 

luego implementar la clase C de la siguiente manera:

public class C : IA, IB 
{ 
    private A _a; 
    private B _b; 

    public C(A _a, B _b) 
    { 
     this._a = _a; 
     this._b = _b; 
    } 

    public void methodA(int value) { _a.methodA(value); } 
    public void methodB(int value) { _b.methodB(value); } 
} 

Generalmente esto es un diseño pobre en general, ya que puede tener tanto A y B implementar un método con el mismo nombre y tipos de variables tales como foo(int bar) y deberá decidir cómo implementarlo, o si solo llama al foo(bar) en _a y _b. Como se sugiere en otro lugar, debe considerar las propiedades .A y .B en lugar de combinar las dos clases.

4

Quiere decir que quiere que la Clase C sea la clase base para A & B en ese caso.

public abstract class C 
{ 
    public abstract void Method1(); 

    public abstract void Method2(); 
} 

public class A : C 
{ 
    public override void Method1() 
    { 
     throw new NotImplementedException(); 
    } 

    public override void Method2() 
    { 
     throw new NotImplementedException(); 
    } 
} 


public class B : C 
{ 
    public override void Method1() 
    { 
     throw new NotImplementedException(); 
    } 

    public override void Method2() 
    { 
     throw new NotImplementedException(); 
    } 
} 
Cuestiones relacionadas