簡體   English   中英

將接口擴展為抽象類

[英]Extend interface to an abstract class

我有一個接口(移動)應該移動一些形狀。

interface Move { move(); }
abstract class Shape : Move

class Circle : Shape
class Square : Shape
class Triangle : Shape

我的疑問是,我必須有一個移動Shapes的界面,但是只能移動Circle和Triangle,那么我如何從Square“移除”界面? 我應該從Shape中刪除界面並在Circle和Triangle上手動添加它嗎? 我有點困惑。 希望有人可以幫助我。

你應該像這樣設置你的類:

interface IMovable { move(); } 
abstract class Shape : { } 

class Circle : Shape, IMovable { } 
class Square : Shape { } 
class Triangle : Shape, IMovable { } 

如果不是每個形狀都可以移動,那么Shape不能實現接口。 另請注意,我將您的界面重命名為IMovable ,這不是一個大問題,但它更受歡迎,更好的命名約定。

您無法從繼承樹中刪除接口。

你的模型似乎需要兩個抽象類 - ShapeMovableShape

interface IMove { move(); } 
abstract class Shape : {} 
abstract class MovableShape : IMove, Shape {} 

class Circle : MovableShape{}
class Square : Shape{}
class Triangle : MovableShape{}

您應該讓自己更熟悉接口,類和OO背后的想法。 您要說的是以下內容:

  • 每個形狀都可以移動。
  • 方形是一種形狀。
  • 但廣場不能移動。

顯而易見,這是沒有道理的。 所以你必須調整你的課堂設計。 可以移動每個形狀,Shape(和Square)應該實現Move,或者不能移動每個形狀,然后Shape不應該實現Move。

試試這個:

interface IMove { move(); }
abstract class Shape { }

class Circle : Shape, IMove { }
class Square : Shape { }
class Triangle : Shape, IMove { }

其他選項可能只是在Shape類中實現IMove.Move方法並默認拋出NotSupportedException

public abstract class Shape : IMove 
{
     public virtual void Move()
     { 
         throw new NotSupportedException();
     }
}

因此,在一天結束時,“任何形狀都可以移動”,但“可移動的形狀應該提供自己如何移動它的實現”。

最后,讓我們假設有一堆形狀以相同的方式移動。 您將創建一個DefaultMovableShape抽象類派生Shape ,它將覆蓋Shape.Move虛擬方法。

public abstract class DefaultMovableShape 
{
     public override void Move()
     {
           // Do stuff
     }
}

最佳答案取決於這些類的用例和環境。 作為開發應用程序或框架的團隊的一部分,采用該團隊使用的設計模式比尋求“完美”解決方案更可取,因為這將使其他人更容易采用和維護您的代碼。

您希望如何使用和擴展這些類也很重要。 您是否期望'Square'將來需要移動? Shape的可移動性是否始終是靜態的,還是作為動態屬性更有用? Move()對於不是形狀的類有什么價值嗎? 如果可移動性可用作動態屬性,請考慮以下因素:

public abstract class Shape
{
     public bool isMovable()
     {
         return false;
     }

     public virtual void Move()
     { 
         if (!isMovable() {
             throw new NotSupportedException();
         } else {
             throw new BadSubclassException();
         }
     }
}

然后,您的子類可以覆蓋isMovable以提供靜態或動態行為,並且可以進一步修改或子類化,只要您的文檔明確指出isMoveable應始終在調用Move之前。 默認行為應基於您希望使用代碼的其他人的期望,具體取決於他們如何實現相關的設計模式。

通過查看集合類在不同框架中的可變性如何發展的歷史,可以找到做出這些決策的挑戰的一個很好的例子。 有些設計中可變類(集合,數組,字典等)已經成為基類,在子類中實現了不變性,反之亦然。 這兩種方法都有有效的論據,也有動態方法,但對於框架用戶來說最重要的因素是一致性,因為正確的是最容易使用的是什么,提供安全性和性能不是損害。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM