2010-02-13 39 views
7

Tôi muốn đạt được điều này trong C#C# đa kế thừa

(Mã giả)

class A; 

class B : A; 

class C : A, B; 

... 

A ac = (A)c; 

... 

B bc = (B)c; 

Đây có phải là có thể?

+0

Không, hãy kiểm tra: http://stackoverflow.com/questions/191691/ http://stackoverflow.com/questions/995255/ –

+0

http://stackoverflow.com/questions/2846752/am-i -trying-to-implement-multiple-inheritance-how-can-i-do-this và http://stackoverflow.com/questions/2456154/does-c-support-multiple-inheritance – Russell

Trả lời

3

No. C# không hỗ trợ đa kế thừa các lớp.

Một lớp học có thể kế thừa từ một lớp và cũng có thể triển khai nhiều giao diện.

+0

@stakx: bắt tốt. Đã sửa. –

0

bạn có thể sử dụng Giao diện cho nhiều lần kế thừa.

2

Không thể thực hiện được trong C#, nhưng bạn cũng nên nghĩ rằng đây có phải là kịch bản bạn thực sự muốn hay không.

C thực sự là một MộtB? Hoặc không C an AB. Nếu điều sau là đúng, bạn nên sử dụng bố cục thay vì thừa kế.

+0

Tôi không thể sử dụng bố cục vì một số lý do. Đã thử điều đó. Vấn đề: Các lớp cơ sở sử dụng các đại biểu và cung cấp các tham chiếu đến chính nó trong cuộc gọi lại. Nếu C bao gồm A và B, các callback chứa các tham chiếu đến A và/hoặc B, không phải C theo yêu cầu. Điều này được đảm bảo nếu tôi kế thừa C từ A và B. Giao diện là một tùy chọn, hãy sử dụng nó. – neil

9

Bạn không cần đa kế thừa trong trường hợp đặc biệt này: Nếu lớp C chỉ được thừa hưởng từ B, bất kỳ trường hợp của lớp C có thể được đúc cho cả BA; kể từ B đã xuất phát từ A, C không cần phải được bắt nguồn từ A một lần nữa:

class A  { ... } 

class B : A { ... } 

class C : B { ... } 

... 

C c = new C(); 
B bc = (B)c; // <-- will work just fine without multiple inheritance 
A ac = (A)c; // <-- ditto 

(Như những người khác đã nói, nếu bạn cần một cái gì đó giống như đa kế thừa, giao diện sử dụng, vì một lớp học có thể thực hiện như nhiều người như bạn muốn.)

+0

Arggh ... Tôi đã giám sát rõ ràng. Cảm ơn gợi ý! Kính trọng – neil

+0

Hmmm. Một vấn đề vẫn tồn tại: Tôi không thể ép buộc C hoạt động như A. B tăng cường A và không cung cấp một chức năng thuần túy nữa (theo yêu cầu). Nói một cách đơn giản, tôi cần một chữ C, đôi khi hoạt động như A và đôi khi là B, tùy thuộc vào ngữ cảnh. – neil

+0

'C' sẽ hoạt động giống như' A' nếu bạn truy cập thông qua 'ac'; tương tự, 'C' sẽ hoạt động giống như' B' nếu bạn truy cập nó thông qua 'bc'. Tất nhiên, nếu bạn có các phương thức ảo, các phiên bản ghi đè sẽ được gọi trong tất cả các trường hợp này. – stakx

0

C# không hỗ trợ đa kế thừa, nhưng như những người khác đã đề xuất bạn có thể sử dụng nhiều giao diện thay thế. Tuy nhiên, ngay cả với các giao diện đôi khi bạn muốn sử dụng lại nhiều triển khai giao diện trong cùng một lớp, mà một lần nữa sẽ thực sự yêu cầu đa kế thừa.

Để giải quyết vấn đề này (mặc dù nó gần như là never needed) Tôi đã đưa ra cách tiếp cận đa thừa kế mô phỏng bằng cách kết hợp partial classesT4 Text Templates. Đó là một hack nhẹ nhưng nó tốt hơn so với sao chép/dán thực hiện giao diện tương tự trong rất nhiều lớp học có nguồn gốc. Dưới đây là một ví dụ đơn giản:

IInterface.cs

public interface IInterface 
{ 
    void Foo(); 
} 

InterfaceImpl.cs

public partial class InterfaceImpl : IInterface 
{ 
    public void Foo() 
    { 
     Console.WriteLine("Foo"); 
    } 
} 

BaseClass.cs

using System; 

public class BaseClass 
{ 
    public void Bar() 
    { 
     Console.WriteLine("Bar"); 
    } 
} 

DerivedClassA.cs

public partial class DerivedClassA : BaseClass, IInterface 
{ 
    public void FooBar() 
    { 
     this.Foo(); 
     this.Bar(); 
    } 
} 

DerivedClassAInterfaceImpl.tt

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassA"); #> 
<#= codeText #> 

DerivedClassB.cs

public partial class DerivedClassB : BaseClass, IInterface 
    { 
     public void BarFoo() 
     { 
      this.Bar(); 
      this.Foo(); 
     } 
    } 

DerivedClassBInterfaceImpl.tt

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassB"); #> 
<#= codeText #> 

Đó là một chút khó chịu mà điều này đòi hỏi việc tạo ra một tập tin tt cho mỗi lớp có nguồn gốc mà muốn sử dụng thực hiện giao diện , nhưng nó vẫn lưu trên mã sao chép/dán nếu InterfaceImpl.cs là nhiều hơn một vài dòng mã. Cũng có thể chỉ cần tạo một tệp tt và chỉ định tên của tất cả các lớp một phần có nguồn gốc và tạo ra multiple files.

Tôi đã đề cập phương pháp này trong một câu hỏi tương tự here.