构造函数主要用来初始化对象。它又分为静态(static)和实例(instance)构造函数两种类别。大家应该都了解如何来写类的构造函数,这里只说下默认构造函数的作用,以及在类中保留默认构造函数的重要性。实际上,我说错了。正确的说法是:以及在类中保留空参数构造函数的重要性。

我们来写一个类A,代码如下:

public class A

{

public int Number;       //数字

public string Word;       //文本

}

//在Test类中实例化

public class Test

{

static void Main()

{

A a = new A(); //实例化,A()即为类A的默认构造函数

Console.WriteLine(“Number = {0}"nWord = {1}”,a.Number,a.Word);

Console.read();

}

}

输出的结果是:

Number = 0

Word =

在上列示例中,我们并没有在A类中明确的写出构造函数,当我们没有提供任何构造函数时,C#自动为类提供了一个默认构造函数,其格式为:

public A()

{

//空白的方法体

}

这个默认构造函数看起来似乎根本没什么作用,没有接收任何输入参数,方法体也是个空的。那么它真的是无所事事,可有可无的一个东西吗?我们回想下前面所讲的构造函数的主要作用,对,它主要用来初始化对象。看下输出结果,int类型的Number被初始化为默认值0,string类型的Word被初始化为默认值空白字符,这些工作都是由看似没起作用的默认构造函数所完成的。

很快,A类的设计让我们并不满意,我们加强了它的能力,自己提供了构造函数:

public class A

{

public int Number;

public string Word;

public A(int number,string word)

{

Number=number;    //标记1

Word=word;       //标记2

}

}

//Test类也重新设计

public class Test

{

static void Main()

{

A a = new A(100,”一百”); //调用了新的带参数构造函数

Console.WriteLine(“Number = {0}"nWord = {1}”,a.Number,a.Word);

Console.read();

}

}

输出结果:

Number = 100

Word = 一百

运行很顺利,结果正确。当我们提供了构造函数时,C#认为我们应该是意识到、并且有能力来做好类的初始化工作,于是它将默认的构造函数撤销,将控制权交到了我们手里。我们自己的构造函数能胜任默认构造函数的工作吗?带着怀疑,我们做个尝试,将类A构造函数的方法体清除,即注释掉标记1和2行,重新运行,输出的结果是:

Number =0

Word =

这个结果和调用默认构造函数的结果是一样的,这证明我们自己提供的构造函数能担当默认构造函数的工作。

不久以后,业务进一步扩展,我们要新构一个类,这个类继承自类A,我们把它称为类B:

public class A

{

public int Number;

public string Word;

public A(int number,string word)

{

Number=number;

Word=word;

}

}

public class B:A

{

public string Name;   //增加一个成员

public B(int number,string word)

{

Number = number;

Word = word;

}

}

//修改Test类

public class Test

{

static void Main()

{

B b = new B(100,”一百”);

Console.WriteLine(“Number = {0}"nWord = {1}”,b.Number,b.Word);

Console.Read();

}

}

运行后出错,错误信息是:“A”方法没有采用“0”个参数的重载。为什么会这样呢?看起来我们并没有什么错误呀。A类提供了构造函数,B类也提供了构造函数。你满腹委屈,含泪望着比尔盖茨。老比怒目圆睁,啪的给你一巴掌:“A类还没构造好,你让我怎么给你构造B类!”。A类?构造?A类还要构造吗?你莫名奇妙了。

事实上,B类要完成构造,必须先完成A类的构造。当我们采用:

public B(int number,string word)

来构造B类时,由于没有明确指明继承的构造方法,C#默认我们继承默认构造函数。

public B(int number,string word):base()

采用这条构造函数时,C# 先调用类A的默认构造函数base()完成基类的构造,然后调用B类的构造函数完成针对B类构造的剩余工作。尝试修改上面的相应代码段为:

//在类A中添加一个空参构造函数

public class A

{

……

public A()

{

Number =1;

Word=”空参构造”;

}

…….

}

//将类B构造函数改为继承A类空参构造

public B(int number,string word):base()

实际上,我是多此一举了,public B(……):base()与public B(……)是一样的,未显式指明构造函数的继承体时,C#就默认为base()。

输出结果

Number=100

Word = 一百

注意看我们给A类添加的空参构造函数,我们在方法体内给Number赋值1,给Word赋值“空参构造”。然而从输出结果看,这些赋值都被覆盖了。这就说明,base()在前,而后才是public B(…..)。

回头来看我们那个错误的例子。遗憾的是,我们在类A中自己提供了构造函数,这导致A类的默认构造函数消失了,当B类从A类继承默认构造函数时,找不到入口了,这就导致了如上的错误。如果要避免错误,有两种方法:1、在A类中添加一个无参数的构造函数。2、B类构造函数显式继承A类的构造函数。

事情已经解释的很清楚了,不过也许还有个小问题,就是:在B类中,我们提供了一个和A类构造函数结构相同的构造函数,为什么C#不能自动识别,自动继承呢?

道理很简单,C#不能靠猜测来判断我们提供的参数究竟是要用作初始化基类还是继承类。还是来看一个例子:

public class A

{

public int Number;

public string Word;

public A(int number,string word)

{

Number = number;

Word = word;

}

}

public class B:A

{

public string Name;

public B(int number,string word,string name):base(number,word)

{

Number = number;

Word = word;

Name = name;

}

}

public class Test

{

static void Main()

{

B b = new B(100,”一百”,”初始化B的参数”);

Console.WriteLine(“Number = {0}"nWord = {1}"nName = {2}”,

b.Number,b.Word,b.Name);

Console.Read();

}

}

输出结果是:

Number = 100

Word = 一百

Name = 初始化B的参数

注意在B类的构造函数中,我们提供了三个参数,其中前两个用于初始化A类中的成员,第三个用于初始化B类的成员。虽然父类构造函数与子类构造函数的参数数量不一样,然而由于我们明确的指定了继承的关系,它们很好的完成了工作。

转载于:https://www.cnblogs.com/tanding/archive/2012/06/27/2564967.html

默认构造函数的作用(“A”方法没有采用“0”个参数的重载相关推荐

  1. [转]默认构造函数的作用

    构造函数主要用来初始化对象.它又分为静态(static)和实例(instance)构造函数两种类别.大家应该都了解如果来写类的构造函数,这里只说下默认构造函数的作用,以及在类中保留默认构造函数的重要性 ...

  2. Java默认构造函数的作用

    Java默认构造函数的作用,有需要的朋友可以参考下. class Person{private String name="";private int age=0;public Pe ...

  3. 在Java中,采用类的默认构造函数构造对象的方法!

    示例代码如下: URL pageURL = new URL(path); 其中URL是一个类,pageURL是对象!

  4. 类的构造函数和析构函数、默认构造函数

    前言 程序只能通过成员函数来访问数据成员,因此需要设计合适成员函数,才能成功地将对象初始化. 类构造函数专门用于构造新对象,将值赋给他们的数据成员,进行初始化. 构造函数名称与类名相同,没有返回值,没 ...

  5. Android6.0 usb默认MTP模式的修改方法

    Android6.0 usb默认MTP模式的修改方法 在6.0以前的系统 只需要修改默认的 persist.sys.usb.config 的值就可以了, 但是6.0,无论你怎能修改persist.sy ...

  6. Entity Framework默认值字段不起作用解决方法

    Entity Framework默认值字段不起作用解决方法 参考文章: (1)Entity Framework默认值字段不起作用解决方法 (2)https://www.cnblogs.com/fox- ...

  7. C#中构造函数的作用

    C#中构造函数的作用 共同点: 都是实例化对象,初始化数据的 默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有, ...

  8. spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入

    spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...

  9. UE4 C++入门之路4-PostInitProperties函数详解(设置属性默认值的四种方法)

    PostInitProperties函数详解 前言 设置属性默认值的四种方法 一 声明时赋值 二 构造函数赋值 三 构造函数初始化列表 四 PostInitProperties 前言 也许在工作或者学 ...

最新文章

  1. Android客户端多线程实例分析
  2. golang channel错误 send to non-chan type int/string
  3. LINUX 上的 Shebang 符号(#!)
  4. sql和泛型方法返回泛型_基于泛型编程的序列化实现方法
  5. html5 获取多媒体,基于HTML5的多媒体支持
  6. pip install mysqlclient报错: error: command ‘gcc‘ failed with exit status 1 OSError: mysql_config no
  7. Python必备收藏!Pycharm 常用快捷键方式!让鼠标离手操作
  8. 中石油训练赛 - Match Matching(完全背包)
  9. Linux运维面试题之--网页打开缓慢如何优化
  10. MAC安装apache tomcat配置方法图文教程
  11. SGU 176 Flow construction(有上下限的最小流)
  12. idea开发java前端_Web前端开发神器 Intellij IDEA
  13. Flutter与原生混合开发
  14. 只用一个div制作太极图
  15. 网页星号点号密码查看最简方法
  16. php开发的在线客服系统,全开源无加密,支持微信客服对接
  17. ZROI 2018 ZYB和售货机(goods)
  18. selenium+java打开新标签页方法
  19. 美国硕士计算机机械专业排名,工科“三巨头”之一-机械工程的美国硕士申请全解答...
  20. 送一台高配电脑,吃鸡贼爽!

热门文章

  1. 关于 spring 使用 mongodb 的 mongotemplate 对象操作数据库,对象注入问题(即该对象能否正常的调用相应的CRUD方法来处理数据)...
  2. Object Tracking using OpenCV (C++/Python)(使用OpenCV进行目标跟踪)
  3. chrome浏览器中解决embed标签 loop=true 背景音乐无法循环的问题。
  4. Spring Boot 学习笔记--整合Thymeleaf
  5. 数据库5 索引 动态哈希(Dynamic Hashing)
  6. 【ThinkPHP】实例化模型的方法
  7. NFC 验证平台搭建
  8. WPF中得到一个控件相对其他控件的坐标
  9. java 怎么页面授权访问_Java调用Linkedin接口API之:获取授权
  10. jmeter中文版新手入门教程