关于Java类的构造方法详解

 更新时间:2023年01月24日 11:48:29   作者:穆哥学堂  
这篇文章主要介绍了关于Java类的构造方法详解的相关资料,需要的朋友可以参考下

​Java语言中,类的构造方法是一种很特殊的方法。关于构造方法要记忆和理解的知识点其实挺多的,下面我们就来详细的讲讲构造方法,相信看过这篇文章之后,你会对构造方法有一个比较深刻的认识和理解。(预警:此文较长,请耐心看完!)

首先来说说构造方法的五个特点:​

一、构造方法的名称必须与类的名称相同。比如类的名称叫A,那么它的构造方法必须也叫A。​

二、构造方法的前面不能声明返回值类型,即便是void也不行。只有满足了这两个条件,编译器才会认定这个方法是构造方法。​

三、如果程序员没有在类中定义构造方法,那么在编译阶段,编译器会“免费赠送”给这个类一个构造方法,也就是说,编译器会在编译阶段在字节码文件中补充添加一个构造方法。但如果程序员已经在类中已经定义了自己的构造方法,则编译器不会再为类添加构造方法。​

四、编译器为类“免费赠送”的这个构造方法是一个没有参数的构造方法。至于说这个构造方法里面有什么内容,咱们一会儿再说。​

五、编译器“免费赠送”的构造方法与类的修饰符相同,也就是说,如果类本身的访问修饰符是public,那么这个编译器“免费赠送”的构造方法的前面也会自动加上public关键字,同理,如果类的前面没有访问修饰符,那么这个构造方法前面也不会有任何任何访问修饰符。​

说完了构造方法的特点,我们再来说说构造方法的作用。很多教科书上都把构造方法的作用说成是为了创建一个对象,其实这种理解是有问题的。必须承认,我们创建一个类的对象必须要调用构造方法,但构造方法的作用其实并不是为了创建对象,而是为了“初始化对象的内部状态”。“初始化对象的内部状态”这句话听起来不太好理解,其实就是为了给对象的各个属性赋初始值。我们来看一个例子:

Java千问25:关于Java类的构造方法,看这一篇就够了!_子类

我们定义了一个Person类,并且给Person类定义了两个属性,分别是String类型的name和int类型的age,并且还定义了一个printInfo()方法,用来打印这两个属性的值。接下来我们在main方法中创建两个Person类对象

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_02

执行程序的结果如下图:

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_03

我们发现,这两个对象的name属性和age属性的值都是默认的那个初始值,这种初始值其实没有太大意义。如果我们希望在创建对象的时候给就对象的两个属性赋上有意义的值,此时我们就可以把给属性赋值的语句写到构造方法当中。

Java千问25:关于Java类的构造方法,看这一篇就够了!_子类_04

有了构造方法之后,我们再次执行main方法,得到的结果是这样的:

Java千问25:关于Java类的构造方法,看这一篇就够了!_继承_05

从运行结果上来看,两个对象的属性都被赋予了有意义的值。但是问题来了:按照这样的写法,我们所创建的每个Person对象,name属性都被赋值为“张三”,而age属性都被赋值为20。这说明我们创建的对象是“千篇一律”的,并且从情理上也说不通,毕竟每个人都有属于自己的名字和年龄,不可能每个人都叫张三年龄20岁。​

那么,如何在创建对象的时候,为每个对象都初始化属于自己的真实数据呢?这时候,我们就要用有参数的构造方法来搞定这个问题了。我们可以给构造方法添加两个参数,通过参数把数据传递给对象的属性。

Java千问25:关于Java类的构造方法,看这一篇就够了!_子类_06

当我们给构造方法添加了两个参数之后,却发现main方法中原来本来正确的代码出现了语法错误。

Java千问25:关于Java类的构造方法,看这一篇就够了!_继承_07

这是为什么呢?就是因为我们给Person类的构造方法添加了参数,现在Person类当中已经没有无参数的构造方法了,既然Person类当中已经没有了无参数的构造方法,那么我们在main方法中调用Person类无参数的构造方法,肯定会报错。​

有人会问:编译器不是会“免费赠送”给每个类一个无参数的构造方法吗?那个送来的构造方法哪去了?这里需要特别说明一下:编译器“赠送”给类无参数构造方法是有条件的,这个条件就是:程序员没有为类定义构造方法。也就是说:只有程序员没有为类添加构造方法的情况下,编译器才会在编译的时候给这个类去自动添加一个无参数的构造方法,现在,程序员已经给Person类定义了构造方法,那么编译器就不会再给这个类添加构造方法了。​

好,回归正题,现在我们想修改这个语法错误很简单,只要在main方法中给Person类的构造方法传递适当的参数就可以了。

Java千问25:关于Java类的构造方法,看这一篇就够了!_构造方法_08

给构造方法传递了参数之后,语法错误自然消失。再次运行程序,会得到这样的结果。

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_09

大家可以看到,这一次,我们就能够按照我们的意愿,创建出有自己个性化的对象了。通过这个例子我们可以看出:构造方法的作用是给对象的各个属性赋上合理的初始值,从而使得我们所创建的对象不再是“千篇一律”,而是“千姿百态”。​

那么,现在我们可以再来思考两个问题:第一个问题:构造方法可以像普通方法那样实现重载吗?这是完全没有问题的,我们可以在一个类中定义多个构造方法,只要这些构造方法参数不同,就构成了重载。第二个问题:在一个构造方法中,可以调用另外一个构造方法吗?也没有问题,但调用的时候,需要注意:不能像调用普通方法那样,通过类名去调用,而是需要用一个关键字this。但是这种调用也有两个条件:​

  • 一、调用构造构造方法的语句必须放在第一行。​
  • 二、两个构造方法不能形成相互调用关系。

为了方便表述,我们把一个类中的两个构造方法代称为X和Y。如果我们在X中调用了Y,那么就不能在Y中去调用X了。否则就会形成循环依赖关系,我们来看下面的例子。

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_10

我们在一个构造方法中调用了另一个构造方法,调用的时候,需要用到this关键字,并且把调用语句写到第一行,这样才能顺利通过编译。​

以上我们讲解的都是关于构造方法的基本常识,在这个讲解的过程中,并没有设计到类的继承关系。如果涉及继承关系,构造方法在定义和调用的过程中也有一些必须了解的知识点。​

首先必须清楚,如果我们创建的是一个子类的对象,那么在创建这个子类对象的时候,虚拟机会先调用父类的构造方法,之后才去调用子类的构造方法。这个顺序不能错,否则会出现语法错误。为了说明问题:我们先来给Person类添加一个无参数的构造方法,并在构造方法中输出一句”父类的构造方法”

Java千问25:关于Java类的构造方法,看这一篇就够了!_继承_11

之后我们再定义出一个Person类的子类Student,并且在子类中也定义一个无参数的构造方法,在构造方法中输出一句”子类的构造方法“

Java千问25:关于Java类的构造方法,看这一篇就够了!_构造方法_12

之后,我们在main方法中创建一个子类对象。

Java千问25:关于Java类的构造方法,看这一篇就够了!_Java_13

运行main方法,得到结果如下图:

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_14

很多人不明白,在子类的构造方法中,只是输出了“子类的构造方法”这样一句话,控制台上为什么同时还输出了“父类的构造方法”?原因就是我们刚才所说的:调用子类构造方法的时候,会首先调用父类的构造方法。即使程序员没有写代码去调用父类的构造方法,编译器也会把调用父类构造方法的语句补充添加到代码中。​

那么,补充添加调用父类构造方法的代码,是如何实现的?这里必须先讲一下子类调用父类构造方法的语法细节:​

  • 一、子类调用父类构造方法的时候,不能通过构造方法本身的名称来调用,必须使用super关键字。​
  • 二、子类在它的普通方法中不能调用父类的构造方法,只能在它自身的构造方法中才能调用。​
  • 三、子类调用父类构造方法的语句,必须写在自身构造方法的第一行。​

这三条语法规则至关重要,请牢记。按照这个语法规则,编译器看到程序员没有在子类构造方法中调用父类构造方法,会按下图所示的方式把调用父类构造方法的语句添加到代码中

Java千问25:关于Java类的构造方法,看这一篇就够了!_子类_15

通过上图可以看到,如果程序员没有在子类构造方法中添加调用父类构造方法的语句,编译器会自动把那条调用语句补充进来,并且放到子类构造方法的第一行。在文章一开始提出了一个问题:编译器会在赠送给我们的构造方法中添加什么内容,此时你应该明白了吧?就是因为在子类的构造方法中调用了父类的构造方法,所以我们才会在控制台上会看到两条输出语句。​

现在又冒出一个问题:父类如果有好几个构造方法,编译器会自动调用哪一个呢?这里必须明确:编译器只会调用那个无参数的构造方法,不会调用有参数的构造方法。这个规则又会引发一个新的问题,那就是:如果父类中压根就没有无参数的构造方法,那怎么办?在这种情况下,编译器就会强制子类定义一个构造方法,并且在它的构造方法中,通过手动调用的形式去调用父类的构造方法,如果你不那么干,编译器就会使出它的杀手锏:划红线!来看下图:

Java千问25:关于Java类的构造方法,看这一篇就够了!_父类_16

既然无论程序员是否愿意,子类在它的构造方法当中必须要调用父类的构造方法,那么,通常情况下我们应该怎样调用父类构造方法才算合理呢?一般来讲,子类都会比父类拥有更多的属性。就本文而言,父类(Person)有2个属性,分别是name和age,而子类(Student)有3个属性,分别是name、age和num。当然,子类的3个属性当中,有2个是从父类那里继承过来的。在创建一个Student对象的时候,必须对这3个属性进行初始化。所以通常子类的构造方法会定义3个参数,这3个参数分别用来初始化子类的3个属性。既然子类的3个属性当中,有2个是继承于父类的,那么就可以用父类的构造方法去初始化那2个继承来的属性,而剩下的那个由子类自身所定义的属性num,可以在子类自身构造方法中实现初始化,看下图

Java千问25:关于Java类的构造方法,看这一篇就够了!_Java_17

通常来讲,子类就是这样调用父类构造方法的。​

最后再回答一个问题:普通方法的名称可以与类名相同吗?答案是:可以!在这种情况下,编译器区分该方法是普通方法还是构造方法,就看方法的前面有没有声明返回值类型。这就是为什么Java语言规定构造方法不能有声明返回值类型的原因。​

希望通过阅读本文,能让你理解构造方法的意义和用法!

到此这篇关于关于Java类的构造方法详解的文章就介绍到这了,更多相关Java类的构造方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Log4j如何屏蔽某个类的日志打印

    Log4j如何屏蔽某个类的日志打印

    这篇文章主要介绍了Log4j如何屏蔽某个类的日志打印,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java 实战图书管理系统的实现流程

    Java 实战图书管理系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+SSM+jsp+mysql+maven实现一个图书管理系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • Java显示程序包不存在的三种解决方法总结

    Java显示程序包不存在的三种解决方法总结

    在Java开发中,有时会遇到“程序包javax.servlet不存在”等错误提示,这通常是因为缺少必要的库或依赖项,这篇文章主要给大家介绍了关于Java显示程序包不存在的三种解决方法,需要的朋友可以参考下
    2024-07-07
  • 解决idea默认带的equals和hashcode引起的bug

    解决idea默认带的equals和hashcode引起的bug

    这篇文章主要介绍了解决idea默认带的equals和hashcode引起的bug,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 使用@Validated和@Valid 解决list校验的问题

    使用@Validated和@Valid 解决list校验的问题

    这篇文章主要介绍了使用@Validated和@Valid 解决list校验的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • java去除中文括号小括号,或者英文括号的实例代码

    java去除中文括号小括号,或者英文括号的实例代码

    这篇文章主要介绍了java去除中文括号小括号,或者英文括号的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 在CentOS上配置Java环境变量的教程

    在CentOS上配置Java环境变量的教程

    这篇文章主要介绍了在CentOS上配置Java环境变量的教程,同时适用于Fedora等其他RedHat系的Linux系统,需要的朋友可以参考下
    2015-06-06
  • Java 两种延时thread和timer详解及实例代码

    Java 两种延时thread和timer详解及实例代码

    这篇文章主要介绍了Java 两种延时thread和timer详解及实例代码的相关资料,需要的朋友可以参考下
    2017-02-02
  • Java之键盘输入语句Scanner解读

    Java之键盘输入语句Scanner解读

    这篇文章主要介绍了Java之键盘输入语句Scanner解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 如何用idea编写并运行第一个spark scala处理程序

    如何用idea编写并运行第一个spark scala处理程序

    详细介绍了如何使用IntelliJ IDEA创建Scala项目,包括配置JDK和Scala SDK,添加Maven支持,编辑pom.xml,并创建及运行Scala程序,这为Scala初学者提供了一个基础的项目搭建和运行指南
    2024-09-09

最新评论