首先要说明的是:抽象类中可以定义构造方法。
在之前认为:1,抽象类是不能实例化的;2,定义抽象类肯定是用来实例化的;3,抽象类中没有构造函数。
这三句话第一句肯定是正确的,第二句和第三句呢,定义抽象类一定要用来继承使用吗?抽象类中没有构造函数吗? (这两个问题会在下面详细解答)
1,抽象类不继承直接用。
就拿前段时间做的图书馆维修管理系统中SqlHelper说吧
代码如下:
- <span style="font-size:18px;"> /// <summary>
- /// 数据访问抽象类
- /// </summary>
- public abstract class SqlHelper
- {
- //数据库连接字符串(web.config来配置),多数据库可使用DbHelperSQLP来实现.
- public static string connectionString = ConnectionString;
- ///<summary>
- ///非查询操作
- ///</summary>
- public static Boolean ExecuteSQL...
- ///<summary>
- ///查询操作
- ///</summary>
- public static DateTable ExecuteQuery...
- }</span>
这样在D层中,就可以直接用抽象类SqlHelper中的方法啦。
这样做有什么好处:1,抽象类直接使用省去了实例化。(分析内存知:类的实例化一要在堆中new出对象,二要在栈中分配空间指向堆中new出的对象),这两步都省去了。
2,抽象类中的静态方法是存在内存中的,用的时候直接去内存中去取,这样还是提高销量。
直接使用需注意的:抽象类中的方法必须为静态的。
2,抽象类中的构造函数
一直都说抽象函数不能被实例化而构造函数是初始化对象的,好像就暗含着抽象类中没有构造函数或者说抽象类中的构造函数没有作用,书上说抽象类不能被实例化至于构造函数有没有,我们试一试不就知道了。
首先来看一下抽象类中没有构造函数的例子。旨在说明构造函数的作用。
实例1:(C#控制台代码)
- class Program
- {
- static void Main(string[] args)
- {
- TestAbstract ta = new TestAbstract ();
- }
- }
- /// <summary>
- /// 定义抽象类
- /// </summary>
- public abstract class BaseAbstract {
- }
- public class TestAbstract:BaseAbstract {
- public TestAbstract()
- {
- Console.WriteLine("子类方法");
- }
- }
实例1结果:
在main函数中,实例化TestAbstract子类时首先去找子类的构造函数进行初始化。至于抽象类中构造函数有没有调用,在实例1中还看不出来。下面请看实例2.
实例2:
- /// <summary>
- /// 定义抽象类
- /// </summary>
- public abstract class BaseAbstract {
- /// <summary>
- /// 定义构造函数
- /// </summary>
- public BaseAbstract() {
- Console.WriteLine("抽象方法");
- }
- }
- public class TestAbstract:BaseAbstract {
- public TestAbstract()
- {
- Console.WriteLine("子类方法");
- }
- }
实例2在实例1的基础上加构造函数。首先看运行会不会提示编译错误,如果错误说明抽象类中不能有构造函数,如过通过,再看看构造函数是不是有用,会不会被子类的覆盖。
运行结果:
如结果所示,抽象类中的构造函数中的内容也打印出来了,说明抽象类中的构造函数是有作用的。
子类继承抽象类时,构造函数不会被覆盖。 而且,在实例化子类对象时首先调用的是抽象类中的构造函数再调用子类中的。
因此,在抽象类中可以使用构造函数封装继承子类公共的东西。
网上有很多篇文章说抽象函数中不能有构造函数,在CSDN上也有几篇说即使有构造函数也用不上的,我也就相信了,直到现在学习分析内存,才想到试一试,实验结果大家也都看到了,跟他们说的不一样。在今后的学习中要带着怀疑的态度去学习知识,不要一味的相信网上说的,也不要一味的不相信他们,遇到分歧,要想到先试一试,事实证明一切。