在本文中,咱们讨论OOP中的热点之一:抽象类。抽象类在各个编程语言中概念是一致的,可是C#稍微有些不同。本文中咱们会经过代码来实现抽象类,并一一进行解析。
深刻理解OOP(五):C#中的访问修饰符(Public/Private/Protected/Internal/Sealed/Constants/Static and Readonly Fields)函数
深刻理解OOP(六):枚举(实用方法)spa
深刻理解OOP(七):属性(实用方法)code
深刻理解OOP(八):索引器(实用方法)htm
深刻理解OOP(九):事件(深刻理解)对象
在微软的MSDN中,对抽象类有以下的定义:blog
用abstract 关键字可定义抽象类,要求其子类必须实现抽象类的函数、属性等。抽象类不可被实例化。抽象类提供了统一的定义,用于其不一样子类直接共享数据、函数。 抽象类也可定义抽象函数。
在Visual Studio中添加Console程序,并命名为“InheritanceAndPolymorphism
”,添加ClassA.cs,添加抽象类ClassA。
using System; namespace InheritanceAndPolymorphism { public abstract class ClassA { } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassA classA = new ClassA(); Console.ReadKey(); } } }
编译报错:
Compile time error: Cannot create an instance of the abstract class or interface 'InheritanceAndPolymorphism.ClassA'
结论:没法用new关键字来实例化一个抽象类。
给抽象类ClassA添加一些非抽象函数的代码:
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassA classA = new ClassA(); Console.ReadKey(); } }
编译,依然报错。 抽象类不管是否有抽象、非抽象函数,均没法经过new关键字来实例化。
咱们把抽象类做为基类,添加ClassB—使之继承自ClassA。
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } } /// <summary> /// Derived class. /// Class derived from abstract class ClassA /// </summary> public class ClassB:ClassA { } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译的结果:再也不报错。
结论:一个类能够继承自abstract 修饰的抽象类,且可被new关键字初始化。
在ClassA中声明YYY函数--无函数体。
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } public void YYY(); } /// <summary> /// Derived class. /// Class derived from abstract class ClassA. /// </summary> public class ClassB:ClassA { } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译,结果报错:
Compile time error: 'InheritanceAndPolymorphism.ClassA.YYY()' must declare a body because it is not marked abstract, extern, or partial
结论是须要对YYY添加函数体,或者添加abstract的修饰符。
在ClassA的YYY前,添加abstract修饰符。
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } abstract public void YYY(); } /// <summary> /// Derived class. /// Class derived from abstract class ClassA. /// </summary> public class ClassB:ClassA { } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译结果,报错:
Compiler error: 'InheritanceAndPolymorphism.ClassB' does not implement inherited abstract member 'InheritanceAndPolymorphism.ClassA.YYY()'
结论:咱们在abstract 类中声明了一个
abstract 的函数,可是并未在其子类ClassB中实现其内容;当使用new关键字初始化ClassB的时候则会报错----没法使用new关键字初始化一个
abstract类。
在子类中添加YYY的实现。
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } abstract public void YYY(); } /// <summary> /// Derived class. /// Class derived from abstract class ClassA. /// </summary> public class ClassB:ClassA { public void YYY() { } } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译结果,报错:
Compile time error: 'InheritanceAndPolymorphism.ClassB' does not implement inherited abstract member 'InheritanceAndPolymorphism.ClassA.YYY()' Compile time warning: 'InheritanceAndPolymorphism.ClassB.YYY()' hides inherited member 'InheritanceAndPolymorphism.ClassA.YYY()'.
结论:要使得子类继承基类的YYY函数,须要用到override关键字,而后才能够用new关键字实例化ClassB。
咱们再看看这些代码:
/// <summary> /// Abstract class ClassA /// </summary> public class ClassA { public int a; public void XXX() { } abstract public void YYY(); } /// <summary> /// Derived class. /// Class derived from abstract class ClassA. /// </summary> public class ClassB:ClassA { public override void YYY() { } } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译,结果报错:
Compiler error: 'InheritanceAndPolymorphism.ClassA.YYY()' is abstract but it is contained in non-abstract class 'InheritanceAndPolymorphism.ClassA'
结果分析:声明abstract的函数,必须同时声明类为
abstract 的函数不能同时添加static或virtual关键字。abstract。
/// <summary> /// Abstract class ClassA /// </summary> public abstract class ClassA { public int a; public void XXX() { } abstract public void YYY(); } /// <summary> /// Derived class. /// Class derived from abstract class ClassA. /// </summary> public class ClassB:ClassA { public override void YYY() { base.YYY(); } } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); Console.ReadKey(); } }
编译,结果报错:
Compile time error : Cannot call an abstract base member: 'InheritanceAndPolymorphism.ClassA.YYY()'
结果分析:ClassB中没法使用base调用基类的abstract函数--由于其不存在。
最后一个问题,能否在抽象类中添加sealed关键字,结果是不能够。
抽象类不能添加sealed、static类修饰符的。
经过下面几点,概括一下本文的结论。
abstract 抽象类
abstract 抽象类能够有子类,其子类实现抽象方法后,可被new实例化对象
如声明了abstract 的函数,则必须声明abstract 的类
当override抽象基类,没法修改基类函数的签名
abstract函数,没法同时添加static、virtual关键字
abstract 类没法被声明为sealed、static类
原文连接:Diving in OOP (Day 4): Polymorphism and Inheritance (All About Abstract Classes in C#)
译文连接:http://www.cnblogs.com/powertoolsteam/p/Diving-in-OOP-Day-Polymorphism-and-Inheritance-All.html