c#用this重载高中数学6种构造函数法的问题:若不重载int型参数,该写什么?

正在播放:方法的重载_构造方法重载_this_static_静态初始化块
下载学院iPad端缓存视频离线看
记录时间点
我的笔记同学的笔记
我的问题同学的问题java重载构造函数,无参数的原方法必须写么?_百度知道
java重载构造函数,无参数的原方法必须写么?
代码如下class SuperClass {
SuperClass() {
System.out.println(&SuperClass()&);
*/SuperClass(int n) {
System.out.println(&SuperClass(& + n + &)&);
}}class SubClass extends SuperClass {
SubClass(int n) {
//super();
System.out.println(&SubClass(& + n + &)&);
SubClass() {
super(300);
System.out.println(&SubClass()&);
}}public class TestSuperSub {
public static void main(String arg[]) {
SubClass sc1 = new SubClass();
//SubClass sc2 = new SubClass(400);
}}当我把 SuperClass() 方法注释掉后,就会报错,可是我程序没有调用到他啊,为什么就不能注释掉呢。解开注释,就正确了。麻烦大侠给解答下!!!
提问者采纳
必须要写,因为一定要有一个空的构造器
提问者评价
谢谢大家的回答。我明白了。
其他类似问题
按默认排序
其他3条回答
SubClass(int n) {
//super();
System.out.println(&SubClass(& + n + &)&);
}你在SubClass类里这样写的 super();
这个意义是调用父类无参数的构造器,其实这一句你可以不用写。一般子类都会默认调用父类无参数的构造器,但是如果没给父类写一个对子类可见的默认无参数构造器的话,就必须在子类的构造器里显式调用父类的 含参数的构造器.因为java创建对象,总是要先要从父类开始创建,因为只有父才有子嘛对不对?你在代码里是没有创建它不错,但是JAVA的机制就是从父类创建开始,而且JAVA里任何一个父类都是继承自java.lang.Object的,它是所有类的基类,JAVA总是从创建这个类开始,然后再一个个向下建立子类
重载时必须写,即使没有方法体。
能讲下原因么,我是初学者不是很懂。
所有类都继承于Object类。不重载时,默认在父类中找构造方法,也就是在Object中。如果重载,系统就会在子类中找构造方法。因为找不到,所以会报错。
貌似函数实例化的时候必须要有构造方法. 实例化子类也一样要构造方法
构造函数的相关知识
您可能关注的推广
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁当你决定了方向,勇气可以带你走得更远。
  构造函数的工作是为了初始化对象的所有成员,而一个类有多个构造函数又是一个非常常见的情景,所有这些构造函数难免会有类似乃至相同的逻辑,并且随着时间的推移,成员变量的增加,功能的改变,构造函数的个数也会不断上升。很多的开发人员一般会先编写一个构造函数,然后将其代码复制粘贴到其他的构造函数当中,以支持在类接口上定义的多个重写构造函数.其实我们不应该这样做,当发现多个构造函数包含类似的逻辑时,我们可以将其提取到一个公共的构造函数中。这样既可以避免代码重复也可以利用构造函数初始化器(constructor initializer)生成更高效的目标代码。
&阅读目录:
      
      
      
      
      
      
1.构造函数之间的相互调用
  构造函数初始化器允许一个构造函数去调用另一个构造函数。通过构造函数之间的相互调用可以有效减少重复代码,下面是一个构造函数之间相互调用的简单示例:
1 public class MyClass
private List&string&
private string
public MyClass():this(0,"")
public MyClass(int initialCount):this(initialCount,string.Empty)
public MyClass(int initialCount,string name)
coll=(initialCount&0)?new List&string&(initialCount):new List&string&();
this.name=
2.使用默认参数减少重复代码
  我们还可以通过使用C# 4.0 的新特性&&默认参数来进一步减少构造函数中的重复代码。我们可以将上面的代码所以的构造函数统一成一个,并为所有的可选参数指定默认值。如果将上面的代码想使用重载来穷举出同样多的功能那么至少需要提供四个构造函数:一个无参数,一个接受initialCount参数,一个接受name参数(调用时需要使用具名参数调用),一个同时接受initialCount参数和name参数。可以看到:
随着参数的增多,需要提供的重载也会直线上升,而使用默认参数可以有效减少构造函数的重复代码,这是一种避免过多重载的良好机制
public class MyClass
private List&string&
private string
private string
public MyClass()
: this(0, string.Empty)
//构造函数使用了可选参数,这里name参数使用""而不是更具语义的Empty因为:Empty不是编译器常量,所以不能作为默认参数
public MyClass(int inititalCount = 0, string name = "")
coll = (inititalCount & 0) ? new List&string&(inititalCount) : new List&string&();
this.name =
  使用默认参数还是提供多个重载的构造函数是一个值得权衡的问题(参见:)。在上面的例子中,只需要后面使用可选参数的构造函数即可满足我们的要求,这里还保留一个无参构造函数是因为:使用了new()约束的泛型类不支持所以参数都有默认值的构造函数,为了满足new()约束,类必须提供显示的无参构造函数。
3.共有构造函数 VS共有辅助方法
&  默认参数是C# 4.0的新特性,C#在4.0之前的版本中必须编写每个需要支持的构造函数。这意味着很多的重复代码,这时我们可以使用构造函数链,让一个构造函数调用声明在同一个类中的另一个构造函数,而不是像C++那也创建一个公有的辅助方法&&因为创建公有的辅助方法会阻碍编译器对代码进行优化。我们看下面的代码(不好):
1 public class MyClass
private List&string&
private string
public MyClass()
CommonConstructor(0, "");
public MyClass(int initialCount)
CommonConstructor(initialCount, "");
public MyClass(int initialCount, string name)
CommonConstructor(initialCount, name);
/// &summary&
/// 一个所有构造函数公有的辅助方法
/// &/summary&
/// &param name="count"&&/param&
/// &param name="name"&&/param&
private void CommonConstructor(int count, string name)
coll = (inititalCount & 0) ? new List&string&(inititalCount) : new List&string&();
this.name =
上面的类使用了一个构造函数公有的辅助方法,和上一个使用默认参数的示例类似,只不过:一个是构造函数间的调用,一个是使用公有的辅助方法。不过在编译时编译器会为使用辅助方法版本的示例中添加一系列的代码:即所有的成员初始化器(参见:),并且还会调用基类的构造函数,所以这回使我们的代码效率大打折扣,并且当我们将name字段定义为readonly的时候会抛出编译错误:
&readonly&字段必须在声明或构造函数中初始化。
最后,我们应该知道创建共有构造函和提供共有的辅助方法数的区别在于:
编译器并不会生成多次调用基类构造函数的代码,也不会讲实例变量初始化器复制到每个构造函数中去。基类的构造函数会被最后一个构造函数调用一次:构造函数定义只能制定一个构造函数初始化器,要么使用this()委托给另一个构造函数,要么使用base()调用基类的构造函数,二者不可兼得。
4.CLR构造类型实例的过程
创建类型的第一个实例所执行的操作顺序图:
在第二个以及之后的实例将直接从第五步开始,因为类的构造器仅执行一次,而且第六步第七步将被优化,以便构造函数初始化器使编译器移除重复的指令,执行顺序如下图:
&  使用C#的构造函数初始化器可以很好的将这些公有的逻辑抽取出来,只需编写一次,也只需要执行一次。到底是使用默认参数还是提供多个构造函数重载需要根据具体的使用场景来抉择,一般情况下应该使用为一个公有的构造函数使用默认参数,并且给出的默认参数值必须永远足够合理,并且不能抛出异常。同时我们需要保证在实例的构造过程中对每个成员变量仅初始化一次,而实现这一点最好的方法就是,尽可能早的进行初始化工作。使用初始化器来初始化简单资源,使用构造函数来初始化需要复杂逻辑的成员,同时将构造函数们的重复逻辑抽取到一个共有得构造函数中,以便减少重复代码。
参考资料&进一步阅读
阅读(...) 评论()第2章掌握C
01:01结构体与类除了在关键字struct与cl..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
构造函数 析构函数 重载函数
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口tickTick 的BLOG
用户名:tickTick
文章数:107
评论数:340
访问量:792270
注册日期:
51CTO推荐博文
&&&&&&& c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特点,并附上例子,希望对初学者有所帮助。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& c++类的构造函数详解&&&&&&&&&&&&&&&&&&&&&&&&
一、 构造函数是干什么的
class Counter
&&&&&& & // 类Counter的构造函数
&&&&&&&& // 特点:以类名作为函数名,无返回类型
& & &&&& Counter()
&& &&&&& {
&&&&&&&&&&&&&&& m_value = 0;
&&&&&&&& }
&&&&& && // 数据成员
& & & && int m_
&&&&&& 该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数-&由构造函数完成成员的初始化工作
eg:&&&&Counter c1;
&&&&&&& 编译系统为对象c1的每个数据成员(m_value)分配内存空间,并调用构造函数Counter( )自动地初始化对象c1的m_value值设置为0
&&&&&&&&构造函数的作用:初始化对象的数据成员。
二、 构造函数的种类
class Complex
&&&&&&& double&&&&m_
&&&&&&& double&&&&m_
&&&&&&&&//&&&&无参数构造函数
&&&&&&& // 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空,什么都不做
&&&&&&& // 只要你写了一个下面的某一种构造函数,系统就不会再自动生成这样一个默认的构造函数,如果希望有一个这样的无参构造函数,则需要自己显示地写出来
&&&&&&& Complex(void)
&&&&&&& & && m_real = 0.0;
&&&&&&&&&&&& m_imag = 0.0;
&&&&&&& //&&&&一般构造函数(也称重载构造函数)
&&&&&&& // 一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)
&&&&&&& // 例如:你还可以写一个 Complex( int num)的构造函数出来
&&&&&&& // 创建对象时根据传入的参数不同调用不同的构造函数
& & & & Complex(double real, double imag)
&&&& & && && m_real =
&&& & && &&& m_imag =&&&&&&&&
& & & && }
&&&&&&& //&&&&复制构造函数(也称为拷贝构造函数)
&&&&&&& //&&&&复制构造函数参数为类对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中
&&&&&&& //&&&&若没有显示的写复制构造函数,则系统会默认创建一个复制构造函数,但当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询 有关 &浅拷贝& 、&深拷贝&的文章论述
&&&&&&& Complex(const Complex & c)
&&&&&&&&&&&&&&& // 将对象c中的数据成员值复制过来
&&&&&&&&&&&&&&& m_real = c.m_
&&&&&&&&&&&&&&& m_img&&&&= c.m_
&&&&&&& }&&&&&&&&&&&&
&&&&&&& // 类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
&&&&&&& // 例如:下面将根据一个double类型的对象创建了一个Complex对象
&&&&&&& Complex::Complex(double r)
&&&&&&&&&&&&&&& m_real =
&&&&&&&&&&&&&&& m_imag = 0.0;
&&&&&&&&// 等号运算符重载
&&&&&&& // 注意,这个类似复制构造函数,将=右边的本类对象的值复制给等号左边的对象,它不属于构造函数,等号左右两边的对象必须已经被创建
&&&&&&& // 若没有显示的写=运算符重载,则系统也会创建一个默认的=运算符重载,只做一些基本的拷贝工作
&&&&&&& Complex &operator=( const Complex &rhs )
&&&&&&&&&&&&&&& // 首先检测等号右边的是否就是左边的对象本,若是本对象本身,则直接返回
&&&&&&&&&&&&&&& if ( this == &rhs )
&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&& return *this;
&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& // 复制等号右边的成员到左边的对象中
&&&&&&&&&&&&&&& this-&m_real = rhs.m_
&&&&&&&&&&&&&&& this-&m_imag = rhs.m_
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&& // 把等号左边的对象再次传出
&&&&&&&&&&&& & // 目的是为了支持连等 eg:&&&&a=b=c 系统首先运行 b=c
&& && &&&&&&&& // 然后运行 a= ( b=c的返回值,这里应该是复制c值后的b对象)&&&&
&&&&&&&&&&&&&&& return *this;
下面使用上面定义的类对象来说明各个构造函数的用法:
void main()
&&&&&&& // 调用了无参构造函数,数据成员初值被赋为0.0
& & & & Complex c1,c2;
&&&&&&&&// 调用一般构造函数,数据成员初值被赋为指定值
&&&&&&& Complex c3(1.0,2.5);
&&&&&&& // 也可以使用下面的形式
&&&&&&& Complex c3 = Complex(1.0,2.5);
&&&&&&& //&&&&把c3的数据成员的值赋值给c1
&&&&&&& //&&&&由于c1已经事先被创建,故此处不会调用任何构造函数
&&&&&&& //&&&&只会调用 = 号运算符重载函数
&&&&&&& c1 = c3;
&&&&&&& //&&&&调用类型转换构造函数
&&&&&&& //&&&&系统首先调用类型转换构造函数,将5.2创建为一个本类的临时对象,然后调用等号运算符重载,将该临时对象赋值给c1
&&&&&&& c2 = 5.2;
& & && // 调用拷贝构造函数( 有下面两种调用方式)
&&&&&&& Complex c5(c2);
& & & & Complex c4 = c2;&&// 注意和 = 运算符重载区分,这里等号左边的对象不是事先已经创建,故需要调用拷贝构造函数,参数为c2
三、思考与测验
1. 仔细观察复制构造函数
&&&&&&&&Complex(const Complex & c)
&&&&&&&&&&&&&&& // 将对象c中的数据成员值复制过来
&&&&&&&&&&&&&&& m_real = c.m_
&&&&&&&&&&&&&&& m_img = c.m_
&&&&&&& }&&&&
为什么函数中可以直接访问对象c的私有成员?
2. 挑战题,了解引用与传值的区别
&&Complex test1(const Complex& c)
& & & & & return
& Complex test2(const Complex c)
& & & && return
&& Complex test3()
&&&&&&&&& static Complex c(1.0,5.0);
& &&&&&&& return
& Complex& test4()
&&&&&&&& static Complex c(1.0,5.0);
&&&&&&&& return
& void main()
& && && Complex a,b;
& && && // 下面函数执行过程中各会调用几次构造函数,调用的是什么构造函数?
& & && test1(a);
& & && test2(a);
& & && b = test3();
& & && b = test4();
& & && test2(1.2);
& & && // 下面这条语句会出错吗?
& & && test1(1.2);&&&& //test1( Complex(1.2 )) 呢?
四、附录(浅拷贝与深拷贝)
&&&&&& 上面提到,如果没有自定义复制构造函数,则系统会创建默认的复制构造函数,但系统创建的默认复制构造函数只会执行&浅拷贝&,即将被拷贝对象的数据成员的值一一赋值给新创建的对象,若该类的数据成员中有指针成员,则会使得新的对象的指针所指向的地址与被拷贝对象的指针所指向的地址相同,delete该指针时则会导致两次重复delete而出错。下面是示例:
【浅拷贝与深拷贝】
#include &iostream.h&
#include &string.h&
class Person
&&&&&&& // 构造函数
&&&&&&& Person(char * pN)
& & & & && && cout && &一般构造函数被调用 !\n&;
& & & & && && m_pName = new char[strlen(pN) + 1];
& & & & & & & //在堆中开辟一个内存块存放pN所指的字符串
& & & & & & & if(m_pName != NULL)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&& //如果m_pName不是空指针,则把形参指针pN所指的字符串复制给它
& & & & & & & &&&& strcpy(m_pName ,pN);
&&&&&&&&&&&&& }
&&&&&&& }&&&&&&&&
&&&&&&& // 系统创建的默认复制构造函数,只做位模式拷贝
&&&&&&& Person(Person & p)&&&&
& & & & & & && && //使两个字符串指针指向同一地址位置&&&&&&&&
&&&&&&&&&&&&&&&& m_pName = p.m_pN&&&&&&&&
&&&&&&& ~Person( )
& & & & & && && delete m_pN
&&&&&&&&char * m_pN
void main( )
&&&&&&& Person man(&lujun&);
&&&&&&& Person woman(man);
&&&&&&& // 结果导致&& man 和&&&&woman 的指针都指向了同一个地址
&&&&&&& // 函数结束析构时
&&&&&&& // 同一个地址被delete两次
// 下面自己设计复制构造函数,实现&深拷贝&,即不让指针指向同一地址,而是重新申请一块内存给新的对象的指针数据成员
Person(Person & chs);
& & & && // 用运算符new为新对象的指针数据成员分配空间
&& & & & m_pName=new char[strlen(p.m_pName)+ 1];
&&& & && if(m_pName)&&&&&&&&
& && &&& {
& & && &&&&& & & // 复制内容
& & & &&&&& & & strcpy(m_pName ,chs.m_pName);
& && &&& }
& & &&& // 则新创建的对象的m_pName与原对象chs的m_pName不再指向同一地址了
&本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)
22:49:08 02:28:02 16:33:42 17:43:31

我要回帖

更多关于 高中数学6种构造函数法 的文章

 

随机推荐