C#中某些多态行为的解释

AL-*_*ami 0 c# polymorphism

我发现可以创建子类的实例并将其分配给父类的变量.我无法绕过这种情况.

在我的代码中,虽然实例是Human类.它在控制台中记录"我是动物"

我有几个问题:

  1. 它甚至意味着什么?

  2. 可能的结果是什么?

  3. 为什么以及何时会有人做这种事情?

家长班:

public class Species
{
    public  String Shout()
    {
        return "I am an animal";
    }
}
Run Code Online (Sandbox Code Playgroud)

儿童班:

public class Human : Species
{
    public new String Shout()
    {
        return "I am a Human";
    }
}
Run Code Online (Sandbox Code Playgroud)

实例:

class Program
{
    static void Main(string[] args)
    {
        Species h = new Human();

        Console.WriteLine(h.Shout());
    }
}
Run Code Online (Sandbox Code Playgroud)

Ian*_* H. 7

如果要有效地使用面向对象编程或OOP,多态性非常有用.

假设你拥有一个动物园.在这个动物园里面(显然)有一些动物.如果您希望将它们全部存储在一个数组或列表中,则在这种情况下,您必须为它们使用基类型Animal.现在,从我们的基类型派生的类Animal共享相同的属性,因此也使用相同的方法.

class Animal
{
    public string Shout ()
    { 
        return "I am an animal!"; 
    }
}
Run Code Online (Sandbox Code Playgroud)

我们现在宣布一个狮子班.

class Lion : Animal
{
}
Run Code Online (Sandbox Code Playgroud)

虽然我们还没有写在Shout里面方法Lion类的实例LionShout提供给他们的方法,因为它们派生Animal类.

但是,如果我们希望Lion课程Shout有所不同呢?我们可以使用virtualoverride关键字.这些可用于属性和方法.virtual表示可以覆盖方法或属性,同时override执行实际覆盖.两者都需要为这个工作设置正确的位置.

要覆盖我们的Shout方法,我们必须将其标记为virtual第一个.

public virtual string Shout () { ... }
Run Code Online (Sandbox Code Playgroud)

现在,在我们的Lion课程中,我们可以对Shout方法执行覆盖.

public override string Shout ()
{
    return "Rooooaaar, I am a lion!";
}
Run Code Online (Sandbox Code Playgroud)

现在我们澄清了这一点,让我们来看看它的一些用法.


Lion lion1 = new Lion();
Run Code Online (Sandbox Code Playgroud)

Lion通过调用类的构造函数来创建类的新实例.如果我们lion1.Shout()现在打电话,我们会得到"Rooooaaar, I am a lion!"返回值.

Animal animal1 = new Lion();
Run Code Online (Sandbox Code Playgroud)

这也有效!由于我们的Lion类派生自基类型Animal,因此该对象可以存储在该类型的对象中Animal.但不要被愚弄!如果我们animal1.Shout()现在打电话,我们仍然会被"Rooooaaar, I am a lion!"退回.

Animal animal2 = new Animal();
Run Code Online (Sandbox Code Playgroud)

这只是基类的一个实例,这意味着该方法animal2.Shout()将返回"I am an animal!".


现在,让我们说,我们有一些更多的动物,Cat,Dog,和Lion.不使用多态,我们无法将它们存储在单个数组中,因为它们没有任何共同之处!但是,如果他们确实来自这个Animal类,我们可以这样做:

List<Animal> animals = new List<Animal>();
animals.Add(new Cat());
animals.Add(new Dog());
animals.Add(new Lion());
animals.Add(new Animal());
Run Code Online (Sandbox Code Playgroud)

以上所有这些都可以完美地运行!

最后,如果你想要从这个元素Animal列表,你要调用一些Dog它特异的方法,你可以(如果它实际上是一个Dog对象,当然)使用animals[1] as Dog将其转换为一个Dog对象.但是,如果它不是Dog对象,您只需nullas操作员处返回.