C#中的抽象类和抽象方法(附带实例)
如果一个类不与具体的事物相联系,只是表达一种抽象的概念或行为,仅仅是作为其派生类的一个基类,这样的类就可以声明为抽象类。
比如去商场买衣服,这句话描述的就是一个抽象的行为。到底去哪家商场买衣服,买什么样的衣服,是短衫、裙子,还是其他样式的衣服?在“去商场买衣服”这句话中,并没有对“买衣服”这个抽象行为指明一个确定的信息。如果要将“去商场买衣服”这个动作封装为一个行为类,那么这个类就应该是一个抽象类。
抽象类主要用来提供多个派生类可共享的基类的公共定义,它与非抽象类的主要区别如下:
由于抽象类本身不能直接实例化,因此很多人认为在抽象类中声明构造函数是没有意义的,其实不然,即使我们不为抽象类声明构造函数,编译器也会自动为其生成一个默认的构造函数。
抽象类中的构造函数主要有两个作用:初始化抽象类的成员和为继承自它的子类使用,因为子类在实例化时,如果是无参实例化,则首先调用父类(包括抽象类)的无参构造函数,然后调用子类自身的无参构造函数;如果是有参实例化,则首先调用父类(包括抽象类)的有参构造函数,然后调用子类自身的有参构造函数。
引入抽象方法的原因在于抽象类本身是一个抽象的概念,有的方法并不需要具体的实现,而是留下让派生类来重写实现。
声明抽象方法时需要注意以下两点:
例如,声明一个抽象类,并在该抽象类中声明一个抽象方法。代码如下:
C# 规定,类中只要有一个方法声明为抽象方法,这个类也必须被声明为抽象类。
当从抽象类派生一个非抽象类时,需要在非抽象类中重写抽象方法,以提供具体的实现,在重写抽象方法时需要使用 override 关键字。
【实例】使用抽象类模拟“去商场买衣服”的案例,然后通过派生类确定到底去哪个商场买衣服,买什么样的衣服。代码如下:
程序运行结果为:
比如去商场买衣服,这句话描述的就是一个抽象的行为。到底去哪家商场买衣服,买什么样的衣服,是短衫、裙子,还是其他样式的衣服?在“去商场买衣服”这句话中,并没有对“买衣服”这个抽象行为指明一个确定的信息。如果要将“去商场买衣服”这个动作封装为一个行为类,那么这个类就应该是一个抽象类。
C#中的抽象类
C# 中声明抽象类时需要使用 abstract 关键字,具体的语法格式如下:访问修饰符 abstract class 类名 : 基类或接口 { //类成员 }声明抽象类时,除 abstract 关键字、class 关键字和类名外,其他的都是可选项。
抽象类主要用来提供多个派生类可共享的基类的公共定义,它与非抽象类的主要区别如下:
- 抽象类不能直接实例化;
- 抽象类中可以包含抽象成员,但非抽象类中不可以;
- 抽象类不能被密封。
由于抽象类本身不能直接实例化,因此很多人认为在抽象类中声明构造函数是没有意义的,其实不然,即使我们不为抽象类声明构造函数,编译器也会自动为其生成一个默认的构造函数。
抽象类中的构造函数主要有两个作用:初始化抽象类的成员和为继承自它的子类使用,因为子类在实例化时,如果是无参实例化,则首先调用父类(包括抽象类)的无参构造函数,然后调用子类自身的无参构造函数;如果是有参实例化,则首先调用父类(包括抽象类)的有参构造函数,然后调用子类自身的有参构造函数。
C#中的抽象方法
在抽象类中定义的方法,如果加上 abstract 关键字,就是一个抽象方法,抽象方法不提供具体的实现。引入抽象方法的原因在于抽象类本身是一个抽象的概念,有的方法并不需要具体的实现,而是留下让派生类来重写实现。
声明抽象方法时需要注意以下两点:
- 抽象方法必须声明在抽象类中;
- 声明抽象方法时,不能使用 virtual、static 和 private 修饰符。
例如,声明一个抽象类,并在该抽象类中声明一个抽象方法。代码如下:
public abstract class TestClass { public abstract void AbsMethod(); //抽象方法 }
C# 规定,类中只要有一个方法声明为抽象方法,这个类也必须被声明为抽象类。
当从抽象类派生一个非抽象类时,需要在非抽象类中重写抽象方法,以提供具体的实现,在重写抽象方法时需要使用 override 关键字。
【实例】使用抽象类模拟“去商场买衣服”的案例,然后通过派生类确定到底去哪个商场买衣服,买什么样的衣服。代码如下:
public abstract class Market { public string Name { get; set; } //商场名称 public string Goods { get; set; } //商品名称 public abstract void Shop(); //抽象方法,用来输出信息 } public class WallMarket : Market //继承抽象类 { public override void Shop() //重写抽象方法 { Console.WriteLine(Name + "购买" + Goods); } } public class TaobaoMarket : Market //继承抽象类 { public override void Shop() //重写抽象方法 { Console.WriteLine(Name + "购买" + Goods); } } class Program { static void Main(string[] args) { Market market = new WallMarket(); //使用派生类对象创建抽象类对象 market.Name = "沃尔玛"; market.Goods = "七匹狼西服"; market.Shop(); market = new TaobaoMarket(); //使用派生类对象创建抽象类对象 market.Name = "淘宝"; market.Goods = "韩都衣舍花裙"; market.Shop(); Console.ReadLine(); } }第 28 行和第 32 行代码分别使用派生类对象创建了抽象类的一个对象,这样在使用该对象时,即可调用抽象类中定义的成员,但是,如果派生类中有单独定义的成员,使用该对象是无法访问的。
程序运行结果为:
沃尔玛购买七匹狼西服
淘宝购买韩都衣舍花裙