构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。
构造函数用来生成并初始化对象多教科书上都把构造方法的作用说成是为了创建一个对象,其实这种理解是有问题的。必须承认,我们创建一个类的对象必须要调用构造方法,但构造方法的作用其实并不是为了创建对象,而是为了“初始化对象的内部状态”。“初始化对象的内部状态”这句话听起来不太好理解,其实就是为了给对象的各个属性赋初始值。我们来看一个例子:
我们定义了一个Person类,并且给Person类定义了两个属性,分别是String类型的name和int类型的age,并且还定义了一个printInfo()方法,用来打印这两个属性的值。接下来我们在main方法中创建两个Person类对象
执行程序的结果如下图:
我们发现,这两个对象的name属性和age属性的值都是默认的那个初始值,这种初始值其实没有太大意义。如果我们希望在创建对象的时候给就对象的两个属性赋上有意义的值,此时我们就可以把给属性赋值的语句写到构造方法当中。
有了构造方法之后,我们再次执行main方法,得到的结果是这样的
从运行结果上来看,两个对象的属性都被赋予了有意义的值。但是问题来了:按照这样的写法,我们所创建的每个Person对象,name属性都被赋值为“张三”,而age属性都被赋值为20。这说明我们创建的对象是“千篇一律”的,并且从情理上也说不通,毕竟每个人都有属于自己的名字和年龄,不可能每个人都叫张三年龄20岁。那么,如何在创建对象的时候,为每个对象都初始化属于自己的真实数据呢?这时候,我们就要用有参数的构造方法来搞定这个问题了。我们可以给构造方法添加两个参数,通过参数把数据传递给对象的属性
当我们给构造方法添加了两个参数之后,却发现main方法中原来本来正确的代码出现了语法错误
这是为什么呢?就是因为我们给Person类的构造方法添加了参数,现在Person类当中已经没有无参数的构造方法了,既然Person类当中已经没有了无参数的构造方法,那么我们在main方法中调用Person类无参数的构造方法,肯定会报错。有人会问:编译器不是会“免费赠送”给每个类一个无参数的构造方法吗?那个送来的构造方法哪去了?这里需要特别说明一下:编译器“赠送”给类无参数构造方法是有条件的,这个条件就是:程序员没有为类定义构造方法。也就是说:只有程序员没有为类添加构造方法的情况下,编译器才会在编译的时候给这个类去自动添加一个无参数的构造方法,现在,程序员已经给Person类定义了构造方法,那么编译器就不会再给这个类添加构造方法了。好,回归正题,现在我们想修改这个语法错误很简单,只要在main方法中给Person类的构造方法传递适当的参数就可以了
给构造方法传递了参数之后,语法错误自然消失。再次运行程序,会得到这样的结果
大家可以看到,这一次,我们就能够按照我们的意愿,创建出有自己个性化的对象了。通过这个例子我们可以看出:构造方法的作用是给对象的各个属性赋上合理的初始值,从而使得我们所创建的对象不再是“千篇一律”,而是“千姿百态”。那么,现在我们可以再来思考两个问题:
我们在一个构造方法中调用了另一个构造方法,调用的时候,需要用到this关键字,并且把调用语句写到第一行,这样才能顺利通过编译。以上我们讲解的都是关于构造方法的基本常识,在这个讲解的过程中,并没有设计到类的继承关系。如果涉及继承关系,构造方法在定义和调用的过程中也有一些必须了解的知识点。首先必须清楚,如果我们创建的是一个子类的对象,那么在创建这个子类对象的时候,虚拟机会先调用父类的构造方法,之后才去调用子类的构造方法。这个顺序不能错,否则会出现语法错误。为了说明问题:我们先来给Person类添加一个无参数的构造方法,并在构造方法中输出一句”父类的构造方法”
之后我们再定义出一个Person类的子类Student,并且在子类中也定义一个无参数的构造方法,在构造方法中输出一句”子类的构造方法“
之后,我们在main方法中创建一个子类对象
运行main方法,得到结果如下图:
很多人不明白,在子类的构造方法中,只是输出了“子类的构造方法”这样一句话,控制台上为什么同时还输出了“父类的构造方法”?原因就是我们刚才所说的:调用子类构造方法的时候,会首先调用父类的构造方法。即使程序员没有写代码去调用父类的构造方法,编译器也会把调用父类构造方法的语句补充添加到代码中。那么,补充添加调用父类构造方法的代码,是如何实现的?这里必须先讲一下子类调用父类构造方法的语法细节:
通过上图可以看到,如果程序员没有在子类构造方法中添加调用父类构造方法的语句,编译器会自动把那条调用语句补充进来,并且放到子类构造方法的第一行。在文章一开始提出了一个问题:编译器会在赠送给我们的构造方法中添加什么内容,此时你应该明白了吧?就是因为在子类的构造方法中调用了父类的构造方法,所以我们才会在控制台上会看到两条输出语句。现在又冒出一个问题:父类如果有好几个构造方法,编译器会自动调用哪一个呢?这里必须明确:编译器只会调用那个无参数的构造方法,不会调用有参数的构造方法。这个规则又会引发一个新的问题,那就是:如果父类中压根就没有无参数的构造方法,那怎么办?在这种情况下,编译器就会强制子类定义一个构造方法,并且在它的构造方法中,通过手动调用的形式去调用父类的构造方法,如果你不那么干,编译器就会使出它的杀手锏:划红线!来看下图:
既然无论程序员是否愿意,子类在它的构造方法当中必须要调用父类的构造方法,那么,通常情况下我们应该怎样调用父类构造方法才算合理呢?一般来讲,子类都会比父类拥有更多的属性。就本文而言,父类(Person)有2个属性,分别是name和age,而子类(Student)有3个属性,分别是name、age和num。当然,子类的3个属性当中,有2个是从父类那里继承过来的。在创建一个Student对象的时候,必须对这3个属性进行初始化。所以通常子类的构造方法会定义3个参数,这3个参数分别用来初始化子类的3个属性。既然子类的3个属性当中,有2个是继承于父类的,那么就可以用父类的构造方法去初始化那2个继承来的属性,而剩下的那个由子类自身所定义的属性num,可以在子类自身构造方法中实现初始化,看下图
通常来讲,子类就是这样调用父类构造方法的。最后再回答一个问题:普通方法的名称可以与类名相同吗?答案是:可以!在这种情况下,编译器区分该方法是普通方法还是构造方法,就看方法的前面有没有声明返回值类型。这就是为什么Java语言规定构造方法不能有声明返回值类型的原因。
构造函数是成员函数的一种名字与类名相同,可以有参数,不能有返回值,void也不行。作用的对对象进行初始化,给成员变量赋初值如果定义是没写构造函数,则编译器默认生成一个无参的构造函数(默认生成的构造函数无参数,不做任何操作)对象生成时,构造函数自动被调用,对象一旦生成,就再也不能在其上执行构造函数一个类可以有多个构造函数构造函数执行必要的初始化工作,有了构造函数就不必在专门写初始化函数,也不用调用复
1.构造函数(1)只要参数和类型不完全相同,就可以定义任意多个构造函数,以适应不同的初始化场合。(2)构造函数不需要写返回
定义结构体的4种方法
## 实现 Java 结构体函数的步骤为了实现 Java 结构体函数,我们需要按照以下步骤进行操作:1. 创建一个 Java 类用来定义结构体的属性和方法。2. 在这个类中定义结构体的属性。3. 在这个类中定义结构体的构造函数。4. 在这个类中定义结构体的方法。下面我们将详细介绍每一步需要做的事情,并提供相应的代码示例。### 1. 创建一个 Java 类用来定义结构体的属性
一.构造函数: 1.构造函数的方法名和类名相同。 2.构造函数没有返回值,不能有return 关键字。 3.多个构造函数以重载的形式存在。 二。 public class Liu { public static void main(String[] args) { new
java里面怎么在对象一旦创建就赋值呢?1.构造方法的作用:.如图: 2.构造函数与普通函数的区别: (1). 一般函数是用于定义对象应该具备的功能。而构造函数定义的是,对象在调用功能之前,在建立时,应该具备的一些内容。也就是对象的初始化内容。jvm调用, 给对象初始化。一般函数是对象建立后,当对象调用该功能时才会执行。 (3). 普通函数可以使用对象多次调用,构造函
构造函数的特点:构造函数基本上定义了两个特点。分别如下:1. 构造函数名必须与其类名称相同 2. 构造函数必须没有显式返回类型构造函数类型:有两种类型的构造函数:1. 默认构造函数(无参数构造函数) 默认构造函数: 没有参数的构造函数称为默认构造函数。默认构造函数的语法如下:class_name ( ){ }默认构造函数的目的是根据类型为对象提供默认值,如:0,null等。2. 参数化构造函数 参
java学习–构造方法 构造方法是一种特殊的方法,它是一个与类同名的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载。创建构造方法的规则 构造函数基本上定义了两个规则。分别如下: · 构造函数名必须与其类名称相同 · 构造函数必须没有显式返回类型Java 构造函数创建无参构造:public class S
目录结构体是什么、声明和定义1.结构体类型的概念2. 结构体的声明与定义2.1 结构体声明(结构布局)2.2 结构体变量声明(创建)2.33. 定义结构体变量的几种方式3.1 先声明结构体类型,再定义结构体变量3.2 在声明结构体类型时,同时定义结构体变量。3.3 直接定义结构体变量,省略结构体名 结构体是什么、声明和定义1.结构体类型的概念结构体是C语言中的一种自己定义构造的类型,它由若干个结
我们人出生的时候,有些人一出生之后再起名字的,但是有些人一旦出生就已经起好名字的。那么我们在java里面怎么在对象一旦创建就赋值呢?1.构造方法的作用:.如图: 2.构造函数与普通函数的区别: (1). 一般函数是用于定义对象应该具备的功能。而构造函数定义的是,对象在调用功能之前,在建立时,应该具备的一些内容。也就是对象的初始化内容。jvm调用, 给对象初始化。一般函数是对象建
构造方法必须满足以下语法规则:(1) 方法名必须与类名相636f70793231313335323631343130323136353331333365663536同。(2)不要声明返回类型。(3)不能被static、final、synchronized、abstract和native修饰。构造方法不能被子类继承,所以用final和abstract修饰没有意义。构造方法用于初始化一个新建的对象,所
在Python语言中,可以使用ctypes模块调用其它如C++语言编写的动态链接库DLL文件中的函数,在提高软件运行效率的同时,也可以充分利用目前市面上各种第三方的DLL库函数,以扩充Python软件的功能及应用领域,减少重复编写代码、重复造轮子的工作量,这也充分体现了Python语言作为一种胶水语言所特有的优势。上篇已经讲了传递数值、指针、字符串参数的例子,详细细节请参考:这次讲一下在Pytho
Java基础八--构造函数 一、子父类中构造函数的特点 1.1 为什么在子类构造对象时,发现,访问子类构造函数时,父类也运行了呢? 原因是:在子类的构造函数中第一行有一个默认的隐式语句。 super(); 构造方法中其实还有一句return;对应返回值中的void 子类的实例化过程:子类中所有的构造
C语言基础06--输入函数 一、getchar() 函数1、格式 2、用法getchar() 函数会检查输入缓冲区是否有数据,如果有数据,直接从输入缓冲区获取一个字符。如果输入缓冲区是空,getchar() 就会发生阻塞,直到有数据输入到输入缓冲区,getchar() 获取到数据之后才会跳出阻塞。 getchar() 只会读取一个字符,输入123,ch1 读取到'1'
深入剖析Java 23种设计模式:从入门到精通设计模式概述设计模式(Design Pattern)是一套被反复使用、多数人知晓、经过分类编目的、代码设计经验的总结。它的核心目的是为了实现代码的可重用性,让代码更易于被他人理解,同时保证代码的可靠性,使代码编写真正工程化,堪称软件工程的基石脉络。设计模 ...
OSPF多区域就是把大网络拆成多个"行政区域",让路由信息传递更高效、更稳定!(就像国家太大,要分省管理,不能所有事都报中央!)OSPF引入区域(Area)的概念,将一个OSPF域划分成多个区域,可以使OSDF支撑更大规模组网。 OSPF多区域的设计减小了LSA泛洪的范围,有效的把拓扑变化的影响控制 ...
随着技术手段的不断升级,企业数据防泄密的方法有很多,真的不胜枚举,本文中,我们就重点聊一聊网络隔离这个方法。网络隔离,很多企业并不陌生,尤其是研发型企业、金融行业、医疗行业等,大部分都是做了网络隔离的,隔离的方式也有很多种,常见的比如网闸、防火墙、VLAN、虚拟化、划分网段和安全域等等,如果对网络隔离建设这块还不是很了解的话,可以看看《企业网络隔离建设指南》这个白皮书资料,里面介绍的很详尽。(PS
ABC 小思维。口胡为主。 ABC407E 反悔贪心题。 由这个题我们导出一个关于合法括号序列的充分必要条件:对于一个长度为 \(2N\) 的合法括号序列 \(S_{2N}\),对于其任意的一个前缀子串 \(S_{1,i},i\in [1,2N]\),这个子串中 ( 的数量一定大于等于 ) 的数量, ...
一、什么是单元测试?通过单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类;单元测试属于最严格的软件测试手段,是最接近代码底层构建的验证手段,能够在软件开发的早期以最小的成本保证局部代码的质量。另外,单元测试都以自动化的方式执行,所以在大量回归测试的场景下执行单元测试,更能提高测试效率,另外,也行帮助开发工程师改善代码