继承和服务类

时间:2010-12-22 17:20:44

标签: .net oop inheritance

我认为OOP中有一些基本的东西:

环境:C#/。net 2.0

假设我有两节课:

public class Animal
{

}
public class Dog : Animal
{

}

具有两种方法的服务类:

 public void DoStuff(Animal animal)
    {
        Console.Write("Animal stuff");
    }
    public void DoStuff(Dog animal)
    {
        Console.Write("Dog stuff");
    }

如果我执行以下代码:

 Animal instance = new Animal();
        MyService.DoStuff(instance);

        Animal instance2 = new Dog();
        MyService.DoStuff(instance2);

“动物的东西”被打印两次。

所以我的问题是:为什么?如何在不转换instance2的情况下获取“Animal stuff”和“Dog stuff”,或者将方法从我的服务移动到我的类(事实上我希望我的代码可以工作,但不是:()

由于

PS:这些只是示例:)


因为访客模式并不吸引人,所以我只是将我的服务方法移到我的班级,等待更好的解决方案。

3 个答案:

答案 0 :(得分:1)

您没有覆盖Dog中的doStuff()方法,因为参数类型不同。它们是两种不同的方法。

更改Dog中的签名以匹配Animal或创建一个为您排序的访问者。

这是编写它的一种方法:

public interface Animal {  void accept(AnimalVisitor visitor); }

public class AbstractAnimal : Animal
{
    public void accept(AnimalVisitor visitor) { visitor.visit(this); } 
}

public class Dog : AbstractAnimal {}

public class Cat : AbstractAnimal {}

public interface AnimalVisitor
{
    void visit(Animal animal);
    void visit(Dog dog);
    void visit(Cat cat);
}

现在服务(以及所有其他服务)可以实现AnimalVisitor并对每个Animal子类型执行不同的操作。

这是一种称为“双重调度”的常见模式;你可以在Scott Meyers的“更有效的C ++”中阅读更多相关内容。

答案 1 :(得分:1)

原因是第二次召唤虽然经过了一只狗,却将参考传递给动物。该引用可以是任何类型的动物(您恰好已经通过了Dog)但.NET不知道所以它必须调用接受对Animal的引用的方法的版本而不是更具体的引用。

答案 2 :(得分:1)

另一件似乎是黑客攻击的事情是将传递的参数强制转换为dynamic。这将允许您实现“动态访问者”,例如,您可以编写

foreach (dynamic a in animals)
  doStuff(a);

void doStuff(Animal a) { ... }
void doStuff(Dog d) { ... }

等等。