2012-08-05 10 views
5

Hãy xem cấu trúc lớp học của tôi. Tôi nghĩ rằng tôi muốn có nhiều niềm vui hơn với thừa kế hơn là có thể.C# - thừa kế tiên tiến

Đầu tiên có một lớp trừu tượng cơ sở:

public abstract class PolicyDetailed 
{ 
    internal abstract DataContainer GetActiveAsset(); 
} 

Tiếp theo đó là một lớp trừu tượng, mà là chung chung:

public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer 
{ 
    internal new abstract T GetActiveAsset(); 
} 

Cuối cùng có một lớp chính sách cụ thể. AccidentContainer thừa hưởng từ DataContainer:

public class PolicyAccident : PolicyDetailed<AccidentContainer> 
{ 
    internal override AccidentContainer GetActiveAsset() 
    { 
     return null; 
    } 
} 

Trong biên soạn tôi nhận được lỗi sau:

'PolicyAccident' does not implement inherited abstract member 'PolicyDetailed.GetActiveAsset()' 

Tôi không chắc chắn những gì bổ tôi nên sử dụng ở đây để làm cho nó làm việc. Có lẽ tôi cũng nên viết những gì tôi muốn đạt được: Tôi có một bộ sưu tập các đối tượng chính sách thuộc loại khác nhau (ví dụ: PolicyAccident, PolicyTravel, vv) kế thừa từ PolicyDetailed với các kiểu DataContainer khác nhau (AccidentContainer, TravelContainer, v.v.). Tôi muốn gọi "GetActiveAsset" phương pháp trên mỗi người trong số họ mà không biết loại cụ thể của họ và tham khảo chúng thông qua PolicyDetailed. Đồng thời tôi muốn mỗi lớp trả lại lớp con Datacontainer cụ thể của họ. Điều đó có thể không?

+0

Bạn có thực sự quan trọng khi tuyên bố rằng các loại vùng chứa cụ thể trả về các loại chính sách cụ thể của chúng? Bạn nói rằng bạn muốn tham chiếu đến các đối tượng được trả về như PolicyDetailed, và theo cách đó bạn sẽ mất thông tin cụ thể! (Hãy nhớ rằng AccidentContainer _IS_ một DataContainer, và một AccidentContainer do đó có thể được trả về từ một phương thức với kiểu dữ liệu trả về mà không thay đổi bất kỳ chữ ký nào) – olagjo

+0

Tôi cần nó ở các phần khác của mã, nơi tôi tham khảo loại chính sách cụ thể và sử dụng nó container bí mật. Tôi có thể xem xét sử dụng hai phương pháp - một trong những sẽ trả về một đối tượng DataContainer, thứ hai có thể trả về một container specifc (nhưng nó cảm thấy loại vụng về :() – Rummy

Trả lời

6

Sự cố là bạn không thể ghi đè phương thức không chung chung trong cùng một lớp khi bạn khai báo bất kỳ phương thức nào khác có cùng chữ ký.

Có một vài lựa chọn:

  • Bởi đến nay đơn giản nhất là để cho hai phương pháp tên gọi khác nhau. Sau đó, bạn có thể đưa ra một thực hiện trong PolicyDetailed<T> mà chỉ đại biểu cho phương thức trừu tượng mới:

    public abstract class PolicyDetailed 
    { 
        internal abstract DataContainer GetActiveAsset(); 
    } 
    
    public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer 
    { 
        internal abstract T GetActiveAssetGeneric(); 
    
        internal override DataContainer GetActiveAsset() 
        { 
         return GetActiveAssetGeneric(); 
        } 
    } 
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer> 
    { 
        internal override AccidentContainer GetActiveAssetGeneric() 
        { 
         return null; 
        }  
    } 
    
  • Bạn thể giới thiệu một mức độ thừa kế, giới thiệu một tên phương pháp mới chỉ chiếc cầu nối mục đích. Điều này là khá xấu xí:

    public class DataContainer {} 
    public class AccidentContainer : DataContainer{} 
    
    public abstract class PolicyDetailed 
    { 
        internal abstract DataContainer GetActiveAsset(); 
    } 
    
    // This only exists to satisfy the base class abstract member, 
    // but at the same time allowing PolicyDetailed<T> to introduce 
    // a new member with the same name. 
    public abstract class PolicyDetailedBridge<T> : PolicyDetailed 
        where T : DataContainer 
    { 
        protected abstract T GetActiveAssetGeneric(); 
    
        internal override DataContainer GetActiveAsset() 
        { 
         return GetActiveAssetGeneric(); 
        } 
    } 
    
    public abstract class PolicyDetailed<T> : PolicyDetailedBridge<T> 
        where T : DataContainer 
    { 
        protected sealed override T GetActiveAssetGeneric() 
        { 
         // Call the *new* abstract method. Eek! 
         return GetActiveAsset(); 
        } 
    
        internal abstract new T GetActiveAsset(); 
    } 
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer> 
    { 
        internal override AccidentContainer GetActiveAsset() 
        { 
         return null; 
        }    
    } 
    
  • Bạn có thể làm việc không chung PolicyDetailed lớp một giao diện thay vào đó, và sử dụng thực hiện giao diện rõ ràng để khai báo một phương pháp trừu tượng mới và vẫn thực hiện giao diện.