2016-05-16 82 views
0

我有以下问题。看看我的代码结构。 如果我的所有派生类在过程(动物a)中具有相同的方法序列,这将是确定的。但想象一下,我有Turtle类,它扩展了Animal,当Process(Animal a)被调用时,里面的方法必须以不同的顺序,并且类Turtle有一些额外的方法,例如Sleep。 在这种情况下我该怎么办? 感谢在C中使用虚拟方法#

public class Animal 
{ 
    public virtual string Eat(){ return "I'm eating"; } 
    public virtual string MakeNoise() { return "I'm ";} 
    public virtual string Go() { return "I'm walking"; } 
} 

public class Dog : Animal 
{ 
    public override string Eat() 
    { 
     return string.Format("{0} {1}",base.Eat(),"a pie"); 
    } 

    public override string MakeNoise() 
    { 
     return string.Format("{0} {1}",base.MakeNoise(),"barking"); 
    } 
} 

public class Controller 
{ 
    public void Process(Animal a) 
    { 
     a.Eat(); 
     a.MakeNoise(); 
     a.Go; 
    } 
} 

public class Client 
{ 
    IList<Animal> animals= new List<Animal>(){Dog,Cat,Turtle,Mouse}; //all animals have base class Animal 
    Controller = new Controller(); 
    foreach(Animal a in animals) 
    { 
     p.Process(a); 
    } 
} 
+4

这改变了'Controler',而不是'Animal'的行为,因此您需要创建重写类型,例如, 'TurtleController' – Rhumborl

回答

2

您可以添加一个重载的方法

public void Process(Turtle t) 
    { 
     //Do what you want here 
    } 
0

你可以写自己一个控制器工厂,将返回一个适当的控制器对于一个给定的动物。为Turtle等创建控制器的子类。在这里我假设我们可以提取接口IControler和IAnimal,但是可以使用抽象基类型。

public class ControllerFactory 
{ 
    public static IController GetController (IAnimal animalToControl) 
    { 
    if (animalToControl is Turtle) { return new TurtleController(); } 
    if (animalToControl is Sheep) { return new SheepController(); } 

    // default 
    return new Controller(); 
    } 
} 

,并呼吁有:

foreach(Animal a in animals) 
{ 
    var p = ControllerFactory.GetController(a); 
    p.Process(a); 
} 

的工厂实现这里是粗糙的,但说明了这一点。

0

每只动物都有Eat,MakeNoiseGo,但是序列因动物而异(加上一些动物的一些额外行为)。对于给定的动物,序列是否总是相同?是他们继承Animal的唯一原因,以便他们可以共享相同的基本行为,并只在需要时才覆盖它们?

如果是这样,那么也许在控制器中而不是Process方法,Animal应该有一个ExecuteBehaviors方法,可以由个别动物覆盖。

public virtual void ExecuteBehaviors() 
{ 
    Eat(); 
    MakeNoise(); 
    Go(); 
} 

然后,如果动物需要不同的顺序,它可以覆盖该方法。 这似乎符合你的问题的描述,让每个动物继承行为,但控制他们的序列,并添加新的行为。

然后在您的控制器中,您可以为每只动物调用ExecuteBehavior。这是工作中真正的多态性。您可以将Animal的任何实例视为相同,并调用相同的方法,无论它是Dog还是Turtle,即使它们的行为会有所不同。

0

您有两种选择,第一种是扩展Process方法。您可以在里面进行切换,并在a.GetType()== typeof(Turtle)时定义顺序。

public class Controller 
{ 
    public void Process(Animal a) 
    { 
     if(a.GetType() == typeof(Turtle) 
     { 
     ((Turtle)a).YourMethod(); 
     } 
     else 
     { 
     a.Eat(); 
     a.MakeNoise(); 
     a.Go; 
     } 
    } 
} 

也可以使动物类,负责过程的方法。 这里的想法我认为不是让动物类负责处理方法。这是控制器开始行动的地方。尝试使用装饰者模式或工厂为每个动物,因为@Brett说