2010-09-14 137 views
2

我有三個類,每個都會返回一個稍微不同的結果。如何讓抽象方法返回具體實現的抽象類型?

// interfact to a king 
public interface IKing{ 
    public Result Get(); 
} 

// main abstract class 
public abstract class King:IKing{ 
    public abstract Result Get(); 
} 

// main abstract result 
public abstract class Result{ 
    public int Type {get;set;} 
} 

// KingA result 
public class ResultA:Result{ 
    ... 
} 

// KingB result 
public class ResultB:Result{ 
    ... 
} 

// concrete implementations 
public class KingA:King{ 
    public override ResultA Get(){ 
    return new ResultA; 
    } 
} 

public class KingB:King{ 
    public override ResultB Get(){ 
    return new ResultB 
    } 
} 

GetKing覆蓋方法是期待Result類這將無法正常工作,也不會接受其子ResultAResultB

我可以採取更好的方法嗎?

+0

有一兩件事我不t就像要求調用代碼的類必須知道轉換,然後確保該方法返回正確的結果類。泛型的使用解決了這些問題。 – Kenoyer130 2010-09-14 21:22:45

回答

4

通常的做法是使用泛型。

public interface IKing<T> where T:Result{ 
    T Get(); 
} 

public class King<T> : IKing<T> 
    public abstract T Get(); 
} 

public class KingA : King<ResultB> { 
    public override ResultA Get(){ 
     return new ResultA(); 
    } 
} 

public class KingB : King<ResultB> { 
    public override ResultB Get(){ 
     return new ResultB(); 
    } 
} 

編輯:固定語法。

+2

「你不能製作覆蓋接口定義的抽象方法」。我同意這可能是多餘的,但它編譯得很好。然而,OP的代碼(和你的版本)有幾個編譯錯誤,包括缺失的parens和一個混亂的類定義。 – 2010-09-14 21:10:25

+0

我結束了翻轉這個,並使用抽象類而不是接口,因爲我想要所有「國王」類的共同屬性。使用泛型的關鍵概念就是我期待的。謝謝! – Kenoyer130 2010-09-14 21:20:07

0

你應該能夠在Get的實現(我假設這是什麼「的具體實現」旨在爲)明確投ResultAResultBResult

1

如果您使用編譯的代碼,它將會有所幫助。你的'具體實現'是假的,看起來你混合了類和方法的概念。否則這裏沒有設計問題。例如:

public class KingA : King { 
    public override Result Get() { 
     return new ResultA(); 
    } 
} 
1

我覺得有一些語法混亂這裏 - 如果我正確捕獲你的意圖,這工作得很好:

// interface to a king 
public interface IKing 
{ 
    Result Get(); 
} 

// main abstract class 
public abstract class King : IKing 
{ 
    public abstract Result Get(); 
} 

// main abstract result 
public abstract class Result 
{ 
    private int _Type; 
    public int Type { get { return _Type; } set { _Type = value; } } 
} 

// KingA result 
public class ResultA : Result 
{ 

} 

// KingB result 
public class ResultB : Result 
{ 

} 

// concrete implementations 
public class KingA : King 
{ 
    public override Result Get() 
    { 
     return new ResultA(); 
    } 
} 

public class KingB : King 
{ 
    public override Result Get() 
    { 
     return new ResultB(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     IKing ka = new KingA(); 
     IKing kb = new KingB(); 

     Result ra = ka.Get(); 
     Result rb = kb.Get(); 

     if (ra is ResultA) 
     { 
      Console.WriteLine("A ok!"); 
     } 

     if (rb is ResultB) 
     { 
      Console.WriteLine("B ok!"); 
     } 
    } 
} 

(編輯格式化)