This article is currently in the process of being translated into Chinese (~91% done).
Abstract classes
抽象类在类定义时用关键字abstract标记,在类的分层架构中主要用于定义基类。这些类的特点是不能实例化它们 - 如果试图去实例化,只会引发编译错误。因此,必需象继承那一章讲解的那样,继承它们生成子类,然后实例化子类。那么什么情况下会需要抽象类呢?这真的要看具体的需求。
老实说,很可能多数情况下都不会需要抽象类,但是抽象类在某些特殊的场景中非常有用,比如架构,这也是.NET framework本身包含不少抽象类的原因。顾名思义 - 抽象类即便不总是,也最常用于表示抽象的事物,那些真实事物之上的更加概念性的东西。
下面的例子会创建一个四足动物(FourLeggedAnimal)的基类,然后继承这个基类创建一个狗(Dog)的类,象这样:
namespace AbstractClasses
{
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog();
Console.WriteLine(dog.Describe());
Console.ReadKey();
}
}
abstract class FourLeggedAnimal
{
public virtual string Describe()
{
return "Not much is known about this four legged animal!";
}
}
class Dog : FourLeggedAnimal
{
}
}如果与继承一章中的例子比较,不会看到多大的差别。实际上出现在FourLeggedAnimal 类定义前面的abstract 关键字就是最大的不同了。上面的例子创建了一个新Dog实例,然后调用从FourLeggedAnimal 类继承的Describe()方法。接下来试试看改为创建一个FourLeggedAnimal 类实例会发生什么:
FourLeggedAnimal someAnimal = new FourLeggedAnimal();
当然就是这样明确的编译错误:
不能创建此抽象类或接口的实例: 'AbstractClasses.FourLeggedAnimal'
此前的代码只继承了Describe()方法,但是对于Dog类来说此方法目前的情况没多大用。把此方法覆盖掉看看:
class Dog : FourLeggedAnimal
{
public override string Describe()
{
return "This four legged animal is a Dog!";
}
}本例实现的是完全覆盖,不过有时还是会需要使用基类的功能,再增加一些新的东西。这可以通过使用base关键字实现。base关键字用于引用当前类直接继承的基类:
abstract class FourLeggedAnimal
{
public virtual string Describe()
{
return "This animal has four legs.";
}
}
class Dog : FourLeggedAnimal
{
public override string Describe()
{
string result = base.Describe();
result += " In fact, it's a dog!";
return result;
}
}比照上述讨论,显然还能创建其它FourLeggedAnimal类的子类 - 猫或狮子?下一章会进一步举例并讲解抽象方法。请继续。