![](/img/trans.png)
[英]Get class type of derived class in base class and pass it as a type parameter
[英]Passing Derived class as a parameter to a method when the parameter type is base class
我是一個新手,並試圖理解繼承和設計模式的概念。
當我瀏覽一些博客時,我遇到了這種模式http://en.wikipedia.org/wiki/Strategy_pattern 。
我發現它很有趣,想要了解更多。 所以我開發了以下程序。
static void Main(string[] args)
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyAdd());
int resultA = context.executeStrategy(3, 4);
context = new Context(new ConcreteStrategySubtract());
int resultB = context.executeStrategy(3, 4);
context = new Context(new ConcreteStrategyMultiply());
int resultC = context.executeStrategy(3, 4);
Console.Read();
}
abstract class Strategy
{
public abstract int execute(int a, int b);
public void Test()
{
Console.Write("tttt");
}
}
class ConcreteStrategyAdd : Strategy
{
public override int execute(int a, int b)
{
Console.WriteLine("Called ConcreteStrategyAdd's execute()");
return a + b; // Do an addition with a and b
}
}
class ConcreteStrategySubtract : Strategy
{
public override int execute(int a, int b)
{
Console.WriteLine("Called ConcreteStrategySubtract's execute()");
return a - b; // Do a subtraction with a and b
}
}
class ConcreteStrategyMultiply : Strategy
{
public override int execute(int a, int b)
{
Console.WriteLine("Called ConcreteStrategyMultiply's execute()");
return a * b; // Do a multiplication with a and b
}
}
class Context
{
private Strategy strategy;
// Constructor
public Context(Strategy strategy)
{
this.strategy = strategy;
}
public int executeStrategy(int a, int b)
{
return strategy.execute(a, b);
}
}
該程序編譯良好,正在工作。 但我的問題是,當Context
構造函數期望基類作為參數時,如何將派生類作為參數傳遞? 鑄造是否隱含發生? 為什么編譯器沒有錯誤?
context = new Context(new ConcreteStrategyAdd());
public Context(Strategy strategy)
{
this.strategy = strategy;
}
簡單地說:
派生類(或子類) 是其基類的實例。
因此,當您將ConcreteStrategyAdd
的實例傳遞給構造函數時,您實際上是在傳遞一個Strategy
對象。
沒有涉及鑄造。 類型層次結構允許這種類型的編程。 它允許程序員在代碼中使用多態 。
由於ConcreteStrategyAdd 是一種策略,因此不需要任何轉換 - 它滿足了作為策略的所有要求。 這是多態性的原理。
也許需要一個更簡單的例子:
abstract class Fruit { }
class Apple : Fruit { }
class Orange : Fruit { }
class Melon : Fruit { }
class FruitBasket
{
void Add(Fruit item) { ... }
}
FruitBasket basket = new FruitBasket();
basket.Add(new Apple()); // Apple IS A fruit
basket.Add(new Orange()); // Orange IS A fruit
basket.Add(new Melon()); // Melon IS A fruit
class Potato : Vegetable { }
basket.Add(new Potato()); // ERROR! Potato IS NOT A fruit.
派生類是基類。 (這是繼承的整個概念:繼承定義了'是'關系)。
另外,請查看Liskov替換原則 。 :)
如果您使用比策略模式更簡單的示例,則更容易理解。
假設你有一個名為“Fruit”的類和一個名為“Apple”的類,它來自水果。 任何與Fruit一起使用的方法一般都可以與Apple或任何其他特定類型的水果一起使用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.