C# 抽象类学习
之前写了个关于接口学习的blog——C# 接口学习,现在在将对抽象类的学习整理下。
一、什么是抽象类
"一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被实例化,进一步说一个抽象类只能通过接口和作为其它类的基类使用."- C++ Programming Language by Stroustrup Chapter13.2
在C#中的关键字 abstract 来定义抽象类和抽象方法。
二、抽象类的特点
1、抽象类可以有实现(包括构造函数)。
2、抽象类中可以有成员变量(包括静态成员变量)、属性、常量和静态方法,并且他们可以是非公共的。
3、抽象类可以从另一个类或一个/多个接口派生。
4、一个类只能从一个抽象类派生。
5、抽象类不能用密封(sealed)来修饰,那就意味着类不能被继承,这违反抽象类被继承的原则。
三、抽象方法和虚方法
1、抽象方法
1)使用 abstract 关键字。例如:public abstract bool Write();
2)抽象方法只能在抽象类中声明,抽象方法必须在派生类中重写。
3)抽象方法可以看成是没有实现体(方法体)的虚方法。
ps:如果类中包含抽象方法,则该类必定定义为抽象类,不论是否还包含其它一般方法。
2、虚方法
1)虚方法使用 virtual 关键字。例如:public virtual bool Write()
2)调用虚方法,运行时将确定调用对象是什么类型的实例,并调用适当的覆写的方法。
3)虚方法必须有实现部分(方法体),子类可以覆盖也可以不覆盖,根据实际要求确定。
四、示例
1、基本示例,抽象类中使用抽象方法,抽象方法是一个没有方法体的方法。
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ShapeClass square = new Square(); int area = square.Area(); Console.WriteLine(area); Console.ReadLine(); } } abstract class ShapeClass { abstract public int Area(); } class Square : ShapeClass { int x = 6; int y = 9; public override int Area() { return x * y; } } }
2、包含抽象方法,虚方法和非抽象方法。当某个类继承于抽象类,那么该派生类必须实现基类中所有的抽象方法。虚方法可以实现也可以不实现。
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MyAbs class1 = new MyClass1(); Console.WriteLine("abs method result: "+class1.absMethod()); Console.WriteLine("general class result: " + class1.method1()); Console.WriteLine("virtual class result: "+class1.virMethod()); Console.ReadLine(); } } abstract class MyAbs { abstract public string absMethod(); public string method1() { return "This is not a abstract method from MyAbs"; } virtual public string virMethod() { return "MyAbs.Virtual"; } } class MyClass1 : MyAbs { public override string absMethod() { return "I'm MyClass1.I override MyAbs.absMetod."; } } }
结果:
3、使得派生自抽象类的派生类同样是抽象类,可以通过不完全实现抽象类的方法实现。
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MyAbs class2 = new MyClass2(); Console.WriteLine(class2.AbsMethod_1()); Console.WriteLine(class2.AbsMethod_2()); Console.ReadLine(); } } abstract class MyAbs { abstract public string AbsMethod_1(); abstract public string AbsMethod_2(); } abstract class MyClass1 : MyAbs { public override string AbsMethod_1() { return "This is MyClass1.AbsMethod_1()"; } } class MyClass2 : MyClass1 { public override string AbsMethod_2() { return "This is MyClass1.AbsMethod_2()"; } } }
结果:
4、抽象类可以从接口继承。我们可以为接口中的方法添加实现,也可以将他们安在抽象方法中。
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MyClass myClass = new MyClass(); Console.WriteLine(myClass.interfaceMethod_1()); Console.WriteLine(myClass.interfaceMethod_2()); Console.ReadLine(); } } interface MyInterface { string interfaceMethod_1(); string interfaceMethod_2(); } abstract class MyAbs : MyInterface { public string interfaceMethod_1() { return "This is MyAbs.I realize interfaceMethod #1"; } public abstract string interfaceMethod_2(); } class MyClass:MyAbs { public override string interfaceMethod_2() { return "This is MyClass.I realize the interfaceMethod #2"; } } }
结果:
Ok,目前,将接口、抽象类。还有虚方法,抽象方法大概复习了一边。接下来要将接口和抽象类做一个简单的比较。