2010-07-08 10 views

risposta

31

C# non ha l'ereditarietà multipla, quindi la linea

Class C : A , B {} 

non funzionerà mai. Si possono fare cose simili con le interfacce, però, lungo le linee di

interface InterfaceA { void doA(); } 
class A : InterfaceA { public void doA() {} } 

interface InterfaceB { void doB(); } 
class B : InterfaceB { public void doB() {}} 

class C : InterfaceA, InterfaceB 
{ 
    m_A = new A(); 
    m_B = new B(); 

    public void doA() { m_A.doA(); } 
    public void doB() { m_B.doB(); } 
} 
+0

+1 Semplice. Al punto. Chiaro. –

4

Non è possibile, C# non supporta l'ereditarietà multipla di classi.

Se fornisci un esempio più concreto di ciò che stai cercando di fare, forse possiamo darti una soluzione migliore (ad esempio, forse la composizione è ciò che cerchi, piuttosto che l'ereditarietà - ovviamente, posso da questo semplice esempio).

1

Non è possibile avere C sia uno A sia uno B a meno che uno di questi non erediti dall'altro.

Tuttavia, se si desidera che lo A e il B non siano comuni a entrambi, utilizzare un'interfaccia.

7

Non si può fare l'ereditarietà multipla in C#, ma è possibile implementare interfacce multiple:

  1. creare un'interfaccia con gli stessi metodi di i membri pubblici di A
  2. Crea un'interfaccia con gli stessi metodi come i membri pubblici B
  3. creare variabili utente per A e B all'interno di C.
  4. Implementare la Un'interfaccia da entrambi A e C (implementazione C chiama semplicemente la sua variabile membro di tipo A)
  5. implementare l'interfaccia B sia B e C (implementazione C chiama semplicemente la sua variabile membro di tipo B)
+4

oppure potresti usare la composizione e creare il tuo percorso personale. :) –

+0

Composizione, FTW. – codekaizen

1

Un'altra modo, che non usa la composizione, usa metodi di estensione. Definisci interfacce senza metodi e implementale con la tua classe C. Quindi, scrivi una classe statica con i metodi di estensione che forniscono implementazioni sulla tua interfaccia.

public static void MyMethod(this InterfaceA a) 
{ 
    // do stuff with a 
} 

lato negativo di questo è che è possibile lavorare solo con quelle proprietà dell'oggetto che sono definite nell'interfaccia. Questo limita le proprietà auto-implementate e le chiamate ai metodi, in pratica.

2

Per il meglio o il peggio C# non supporta l'ereditarietà multipla. Tuttavia, ho avuto un successo limitato nella simulazione usando extension methods. L'approccio al metodo di estensione potrebbe essere simile a questo.

public class A 
{ 
    public void DoSomething() { } 
} 

public static class B 
{ 
    public static void DoSomethingElse(this A target) { } 
} 

public class C : A 
{ 
} 

Il problema evidente è che C non è sicuramente un B. Quindi l'unica cosa buona è evitare il codice duplicato in alcune situazioni.

D'altra parte C# supporta l'implementazione di più interfacce. Sarebbe come questo.

public interface IA 
{ 
    void DoSomething(); 
} 

public interface IB 
{ 
    void DoSomethingElse(); 
} 

public class A : IA 
{ 
    void DoSomething() { } 
} 

public class B : IB 
{ 
    void DoSomethingElse() { } 
} 

public class C : IA, IB 
{ 
    private A m_A = new A(); 
    private B m_B = new B(); 

    public void DoSomething() { m_A.DoSomething(); } 

    public void DoSomethingElse() { m_B.DoSomethingElse(); } 
} 

Il problema ovvio qui è che mentre si eredita l'interfaccia non si eredita l'implementazione. Questo è utile per il polimorfismo, ma è dannoso per evitare il codice duplicato.

A volte è possibile utilizzare entrambe le strategie per raggruppare insieme qualcosa che assomiglia a un'ereditarietà multipla, ma probabilmente sarà difficile da comprendere e mantenere. Se la tua situazione richiede realmente ereditarietà multiple, le tue opzioni saranno limitate e certamente non ideali, ma esistono comunque.

+2

Mi sembra di pensare che l'esclusione di MI sia in peggio. Ma è perché penso che l'argomento della complessità sia per lo più superato. Credo che tutti noi abbiamo le nostre opinioni, ma questa è una che sono più schietto su ... nel bene e nel male, ovviamente :) –

0

Quindi credo che cant essere fatto in modo ...

class A : DependencyObject 
    { 
     public int X 
     { 
      get { return (int)GetValue(XProperty); } 
      set { SetValue(XProperty, value); } 
     } 
     public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(int), typeof(A), new UIPropertyMetadata(0)); 
    } 

    class B : DependencyObject 
    { 
     public int X 
     { 
      get { return (int)GetValue(XProperty); } 
      set { SetValue(XProperty, value); } 
     } 
     public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(int), typeof(B), new UIPropertyMetadata(0)); 
    } 

    class C : DependencyObject 
    { 
     A a = new A(); 
     B b = new B(); 
     public int X 
     { 
      get { return a.X; } 
      set { a.X = value; } 
     } 
     public int Y 
     { 
      get { return b.X; } 
      set { b.X = value; } 
     } 
    } 
1

È possibile raggiungere questo obiettivo multilivello Eredità ...

public class DependencyObject 
{ 
    public void DependencyObjectMethod() { } 
} 

public class A : DependencyObject 
{ 
    public void MethodA() { } 
} 

public class B : A 
{ 
    public void MethodB() { } 
} 

public class C : B 
{ 
    public void MethodC() 
    { 
     //Do Something 
    } 
} 

Con questo è possibile ottenere l'accesso a tutti i metodi e proprietà di quelle classi.