Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 继承和服务类_.net_Oop_Inheritance - Fatal编程技术网

.net 继承和服务类

.net 继承和服务类,.net,oop,inheritance,.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) { Con

我认为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,或者将方法从我的服务移动到我的类中(事实上我希望我的代码可以工作,但不是:()

谢谢

附:这些只是例子:)



因为访问者模式不是很吸引人,所以我将把服务的方法移到我的类中,等待更好的解决方案。

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

要么更改Dog中的签名以匹配动物,要么创建一个访客为您排序

这里有一种写的方法:

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,并对每个动物子类型执行不同的操作


这是一种常见的模式,称为“双重分派”;您可以在Scott Meyers的“更有效的C++”中了解更多信息

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

要么更改Dog中的签名以匹配动物,要么创建一个访客为您排序

这里有一种写的方法:

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,并对每个动物子类型执行不同的操作


这是一种常见的模式,称为“双重分派”;您可以在Scott Meyers的“更有效的C++”中了解更多信息,原因是第二次呼叫虽然传递了一只狗,但传递了一个参考。该引用可以是任何类型的动物(您只是碰巧传递了一只狗),但.NET不知道这一点,因此它必须调用接受对动物引用的方法版本,而不是更具体的引用。

原因是,第二个调用虽然传递了一只狗,但却传递了对动物的引用。该引用可以是任何类型的动物(您只是碰巧传递了一只狗),但.NET不知道这一点,因此它必须调用接受对动物引用的方法版本,而不是更具体的引用。

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

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

void doStuff(Cat c) { ... }
void doStuff(Dog d) { ... }

等等。这可以让您完全避免“双重分派”方法,因为您使用的是动态分派。请注意,这种方法的计算量要大得多,在某些(如迭代)场景中可能不可行。

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

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

void doStuff(Cat c) { ... }
void doStuff(Dog d) { ... }

等等。这可以让您完全避免“双重分派”方法,因为您使用的是动态分派。请注意,这种方法的计算量要大得多,在某些(如迭代)场景中可能不可行。

doStuff不是狗或动物类的一部分,你能解释一下访客吗?我刚刚读了更多关于这种模式的内容,确实它似乎是一种解决方案,但是它有一些默认设置:1/需要实现很多代码,2/我们失去了服务类的好处:我们有办法在动物类中找到它的方法,3/如果你不知道这个模式,你就不知道发生了什么!我想我知道这个模式;你不知道发生了什么事。1.“很多代码”-我不知道你是从哪里得到这个想法的。当然,有一些代码,但不是很多。2.当我写这篇文章时,你的动物和狗类根本没有方法。我不能说“动物类中服务方法的一种方法”,因为没有实现。3.我不知道模式?你得查一下。我会说你是那个不知道发生了什么事的人。@remi,我看不到关于狗或动物类的任何东西,因为它们都是空的。访问者将doStuff移出所访问的类,因此它满足了这个要求。”:AbstractAnimal“,这就是我所说的方式。如果“accept”方法中有更多参数,我该怎么办?我从来没有说过你不知道这个模式,为什么我会这么说,我只是在说我和我的同事。doStuff不是狗或动物类的一部分,你能解释一下访客吗?我只是读了更多关于这个模式的书,它看起来确实是一个解决方案,但它有一些默认:1/它需要很多代码来实现,2/我们失去了服务类的好处:我们有办法在动物类中使用它的方法,3/如果你不知道这种模式,你就不知道发生了什么!我想我知道这个模式;你不知道发生了什么事。1.“很多代码”-我不知道你是从哪里得到这个想法的。当然,有一些代码,但不是很多。2.当我写这篇文章时,你的动物和狗类根本没有方法。我不能说“动物类中服务方法的一种方法”,因为没有实现。3.我不知道模式?你得查一下。我会说你是那个不知道发生了什么事的人。@remi,我看不到关于狗或动物类的任何东西,因为它们都是空的。访问者将doStuff移出所访问的类,因此它满足了这个要求。”:AbstractAnimal“,这就是我所说的方式。如果“accept”方法中有更多参数,我该怎么办?我从来没有说过你不知道这个模式,为什么我会这么说,我只是在谈论我和我的同事。好吧,但如果多斯塔夫是动物和狗类的一部分,为什么这会起作用呢?尽管如此.net还是会引用动物,但它