C#规定,抽象类不能实例化,如下代码会发生编译错误:

Animal myanimal=new Animal();

那么如下代码正确吗?

Animal myanimal=new Dog();
myanimal.Cry();

这段代码是完全正确的。既然抽象类不能实例化,那么这段代码为什么又可以运行呢?首先要明确上面的代码并没有实例化抽象类,只是声明了一个抽象类的对象myanimal,实例化时必须通过构造函数来实现,这里调用的是子类的构造函数,所以实例化的是子类对象,只是抽象类对象引用了子类实例。那么这个对象是子类还是父类呢?

using System;
public abstract class Animal
{
public abstract void Cry();
public void Show()
{
    Console.WriteLine("这是抽象类中的方法");
}
}

public class Dog: Animal
{
public override void Cry()
{
    Console.WriteLine("狗的叫声是汪汪");
}
public void ShowDog()
{
    Console.WriteLine("这是派生类的方法");
}
}

class Progarm
{
static void Main()
{
    Animal animal = new Dog();
    animal.Cry();
    animal.Show();
}
}

抽象类对象调用了子类的Cry()方法和本身Show()方法,子类的ShowDog()方法是不能访问的。说明抽象对象引用子类实例后,基本上还是属于抽象类,能够访问子类重写的方法和父类自己的属性和方法,子类自己的属性和方法是不能访问的。

扩展:如果有很多种动物,每个动物都要实例化,然后输出,工作量很大,也不是最佳表达方式。下面用数组来组织这些动物,主函数中的测试代码修改为以下代码

Animal[] animals=new Animal[3]{new Dog(),new Cat(),new Sheep()};

foreach (Animal a in animals)
{
a.Cry();
}

注意:抽象类的派生类必须实现所有的抽象方法,必须使用override关键字,并且不能是私有的。