2013-05-30 189 views
1

我有一个名为IStrategy接口:接口继承

public interface IStrategy 
{ 
} 

我有一个名为IClickStrategy另一个接口,从IStrategy继承。它有)称为GetClicks(方法:

public interface IClickStrategy : IStrategy 
{ 
    void GetClicks(string[] args); 
} 

以及从继承IClickStrategy一类并实现GetClicks()方法:

public class UnionenClicksController : IClickStrategy 
{ 
    Models.DMDelivery.Unionen model; 
    Logger logger; 

    public UnionenClicksController() 
    { 
     this.model = new Models.DMDelivery.Unionen(); 
     this.logger = new Logger(); 
    } 

    public void GetClicks(string[] args) 
    { 
     ... 
    } 
} 

在我的主要方法,这取决于关于策略的类型,我想决定做什么。因此,在我拥有的一切之前:

IStrategy strategy = null; 

然后,如果输入参数想获得点击信息,我想从我的类UnionenClicksController()调用GetClicks函数。

enter image description here

但可以看出,我看不到GetClicks()功能。但是,如果我将我的策略更改为IClickStrategy,那么它会看到我的GetClicks。但这不是我想要的,因为除了点击之外,我可能会采用不同的策略,并且我不想在主要方法的开始处声明它。

我做错了什么?谢谢。

+0

你不能设置一个公共的一个接口的方法,你运行一个自定义的编译器跳过接口错误的情况下? – Deukalion

+0

@Deukalion我修正了这个问题。谢谢。 – Disasterkid

回答

1

IStrategy不包含GetClicks,它被发现在IClickStrategy接口中。

变化

IStrategy strategy = null; 

IClickStrategy strategy = null; 

您也可以尝试强制转换为合适的接口,

如果你确定它实现了正确的接口:

((IClickStrategy)strategy).GetClicks(); 

如果你不确定:

var s = strategy as IClickInterface; 
if (s != null) 
{ 
    s.GetClicks(); 
} 
+1

“但这不是我想要的,因为除了点击之外,我可能有不同的策略,我不想在我的主要方法开始时声明它。” –

+1

然后你必须施放它。 – Zbigniew

+0

@Daniel Daranas然后使用泛型,如果你在运行时不知道如何施放它们。或通过反思以某种方式确定课程。 – Deukalion

1

你必须要么塑像为每一种情况下,或者在IStrategy是选择正确的方法的虚方法。

如果一个对象实施多种策略,后一种解决方案是不可能的。

+0

当我在每个案例上创建一个新的策略对象,然后调用它的GetClicks方法时,它的工作原理如下: – Disasterkid

+0

IClickStrategy strategy = new UnionenClicksController(); strategy.GetClicks(参数);但是您能否详细说明您的虚拟方法解决方案? – Disasterkid

+0

虚拟方法解决方案:'interface IStrategy {void GetWhatever(string []); }'和'class ClickStrategy:IClickStrategy {public void GetWhatever(string [] args){return GetClicks(args); } public void GetClicks(string [] args){...}}' – Medinoc

0

试试吧

IClickStrategy strategy = null; 

因为UnionenClicksController不继承IStrategy。

+0

我不想这样做,因为我的策略可能不总是点击策略。所以我不想这样宣布。根据switch语句中的输入参数,我将实现天气,我应该运行点击策略或不运行。 – Disasterkid

1
IStrategy strategy = null; 

. 
. 
. later on you find that you need to see if it contains a IClickStrategy .. 
. 

IClickStrategy clicker = strategy as IClickStrategy; 

if(clicker != null) { 
    clicker.GetClicks(...); 
} 
+0

根据具体情况,您可能需要也可能不需要'else {new MyDefaultClickStrategy()。GetClicks(...); }' – Medinoc

+0

@Preet Sangha:这看起来不错,但它再次给了我一个NullPointerException。 – Disasterkid

0

当然可以。但编译器不知道这一点。你只要告诉他,你想把strategy当作IStrategy。你对此非常明确。现在...

不要混淆名称strategy与您的UnionenClicksControler对象 - 它只是该对象的名称。这个名字有一个类型。如果你想在GetClicks()方法,只是做:

(strategy as IClickStrategy).GetClicks(args); 

我还没有尝试过这个自己还没有,因为我还没有得到周围,但这样做

dynamic strategy; 

也可能会解决您的问题...但你可能失去任何智能感知魔力......

+0

两种情况都为空引用异常。 – Disasterkid

0

尝试使用这样的:

if(strategy is IClickStrategy) 
    (strategy as IClickStrategy).GetClicks(); 

从技术上讲,您需要首先检查对象的类型,然后将其转换为查看继承接口的方法。

0

感谢所有的答案,但我发现了两个解决我的问题:

首先,是不使用行:

IStrategy strategy = null; 

而推迟,直到每一个switch语句后再申报策略作为IClickStrategy。

二,如果我想保留我的IStrategy strategy = null; line我把我的IStrategy界面中的GetClicks方法提升了一级,并给它一个更一般的名称:GetItems

现在我的开关情况是这样的:

case "GETCLICKSUNIONEN": 
    strategy = new UnionenClicksController(); 
    strategy.GetItems(args);        
    break;