你为什么要使用不同的类变量?

时间:2014-03-03 00:36:43

标签: c# polymorphism base-class

关于多态性,我的书和youtube视频都撇开了你可以这样做的事实: Animal max = new Dog();

现在我已经看到了一个使用数组创建列表的示例,这个场景对我来说非常有意义。

然而,在我之前的例子中,我无法理解为什么我不会写

Dog max = new Dog();

max将变量设置为Animal,假设Dog:Animal继承,获得什么?

4 个答案:

答案 0 :(得分:1)

在你的例子中,确实没有优势。一个更典型的场景强调多态性的力量如下:

public class Foo
{
    public Animal GetAnimal()
    {
        return new Dog();
    }
}

public class Bar
{
    public void DoSomething()
    {
        Foo foo = new Foo();
        Animal animal = foo.GetAnimal();
    }
}

那么,为什么不在方法中返回Dog而不是动物呢?因为良好的编码实践告诉我们返回最少的派生类,这足以提供对成员的访问。更可能的情况是返回一个接口:

public class Foo
{
    public IAnimal GetAnimal()
    {
        return new Dog();
    }
}

在实际场景中,我遇到的最常见的情况是返回IEnumerable<T>的方法,但实际上返回一个数组。为什么不直接返回阵列?因为消费者只需要一系列元素,而不是底层数据结构。

答案 1 :(得分:0)

这个原因是你以后可以把它变成另一种动物。

例如)

Animal pet = new Dog();

// you do some thing else .. assume your pet is currently dog and your apartment can collect this detail as an animal.. 
// now your dog ran away :D and you have cat as your pet 
// all you have do is just change the variable to point to cat instance

pet = new Cat(); //ofcourse Cat should inherit Animal

所以它具有灵活性

现在假设,您的公寓可以为pets

执行许多常用方法

e.g)

public Pass issuePass(Animal pet)
{
  return new Pass(pet.gettype(),pet.getowner(),pet.getname());
}
//you dont need to change this method.
//otherwise you need to create new methods unneccesarily

public Pass issuePass(Dog pet)
{
  return new Pass(pet.gettype(),pet.getowner(),pet.getname());
}
    public Pass issuePass(Cat pet)
{
  return new Pass(pet.gettype(),pet.getowner(),pet.getname());
}

答案 2 :(得分:0)

多态性涉及许多与面向对象编程相关的其他概念。

其中一个是耦合。如果一个类(即Vet有一个方法将Dog作为参数(void Treat(Dog dog)),那么这两个类紧密耦合 - {{ 1}} 依赖 Vet

通过接受Dog作为参数(Animal),您可以实现更高级别的解耦。 void Treat(Animal animal)现在取决于Vet,这是一个更抽象的概念,而不是Animal这是一个具体的概念。

为了进一步了解这一点,研究5种SOLID原理和“高内聚,松散耦合”。

这带来了另一个概念 - 灵活性。 Dog方法现在更灵活,可以适用于任何动物。

答案 3 :(得分:0)

你是对的,当你对new Dog()的实例化进行硬编码时,它没那么有用。当你隐藏动物变量中存储的动物种类时,你会获得更多的价值。这完全将实现与接口分离。

Animal animal = AnimalFactory.GetAnimal();

现在这种动物可能是一只狗或一只猫。由于两者都是动物,因此您不需要知道它是什么类型的动物,因为所有动物都支持您与之交互的基本界面。

这样可以轻松更换组件,而不会丢失程序,也便于轻松测试。


即使你没有抽象出混凝土类型,我也会说总是编程到最通用的界面是一种好习惯。如果您没有使用任何特定于狗的功能,那么为什么要将它存储在dog变量中。将其存放在动物体内使得更清楚的是仅使用动物特征。未来的维护者可以看到并且知道将狗换掉另一只动物是安全的。