0


Java类和对象(接上篇博文)

在这里插入图片描述

🎉🎉🎉写在前面:
博主主页:🌹🌹🌹戳一戳,欢迎大佬指点!
博主秋秋:QQ:1477649017 欢迎志同道合的朋友一起加油喔💪
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个小菜鸟嘿嘿
-----------------------------谢谢你这么帅气美丽还给我点赞!比个心-----------------------------

在这里插入图片描述

Java类和对象

🌈七,构造方法

首先在进入构造方法之前,先问大家一个问题:大家觉得一个对象的产生需要几步,具体过程?

答案是会经过两步:

🌕1,为对象分配内存空间。

🌕2,调用合适的构造方法

这里就提到了构造方法,那到底什么是构造方法,下面会做详细的介绍:


🌟7.1,构造方法的概念

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

在这里插入图片描述

当我们在new对象的时候,就会调用构造方法,当我们没有提供构造方法的时候,编译器会自动提供一个没有参数的构造方法。注意,构造方法的作用仅仅是为了构造对象,不负责分配空间。


🌟7.2,构造方法的特性

🌕1,在定义构造方法的时候,方法名必须和类名相同。

🌕2,构造方法是没有返回值的,设置为void也不行,简单点说就是不写。

🌕3,在创建对象的时候会自动调用构造方法,并且在对象的生命周期内只会调用一次。

🌕4,构造方法是可以重载的,这也就是为什么说在创建对象的时候会调用合适的构造方法,因为可能存在多个参数不同的构造方法。

classPerson{privateString name;privateint age;publicPerson(){System.out.println("Person<> init");}publicPerson(String name,int age){this.name = name;this.age = age;System.out.println("Person<String,int> init");}@OverridepublicStringtoString(){return"Person{"+"name='"+ name +'\''+", age="+ age +'}';}}publicclassTestDemo220507{publicstaticvoidmain(String[] args){Person per1 =newPerson();//它会去调用无参的那个构造方法System.out.println(per1);System.out.println("=========================");Person per2 =newPerson("xiaowang",20);//它会去调用有参的那个构造方法System.out.println(per2);}}

程序运行截图:

在这里插入图片描述

所以说呢,在实例化对象的时候,我们会调用构造方法,并且也是可以传参的,根据参数的不同,我们在实例化对象的时候只会调用相应的构造方法。


🌕5,如果说用户没有自己定义构造方法,那么我们在实例化对象的时候编译器会自动生成构造方法并且调用,但是记住,这个默认的构造方法一定是无参的。

🚩注意:这里有特别注意的一个点,就是一旦用户自己定义了,那么编译器就不会自动生成了。因为编译器只能是自动生成无参的,但是特别怕的是我们自己定义了一个有参构造方法,这个时候如果我们想去定义一个新的对象,并且是一个无参的,那么这个时候编译器就不会自动生成了,所以这个时候这个无参的构造的函数只能用户自己定义,不然就直接报错了。❌❌❌

在这里插入图片描述

可以看到,如果我们将上面那段代码里面的无参构造方法删除后,代码就直接报红了。


🌕6,在构造方法的内部如果对成员属性进行赋值要善用this。

🚩注意:既然这里提到了this,那有一个面试的问题就是为什么说this代表的是当前对象的引用,而不是对象本身呢?对呀,这是为什么呢,我百思不得其解…

在这里插入图片描述

后来在我们的大学城B站上,看到了一位名叫大博哥的牛人的讲解,一下子我就开窍了,原因其实很简单,依旧是先有鸡还是先有蛋的问题。

原因解析:因为前面说了我们创建对象的过程是先分配内存空间,然后再调用构造方法创建对象,但是我们有可能在构造方法的内部就需要使用this,但是这个时候还在走构造方法,所以对象是还没有存在的,那你怎么会用得到对象呢,所以this在这里是不可能代表对象的,但是对象的内存空间是已经分配好了的,所以this代表的是这块内存空间,也即是对象的引用,利用对象的引用去操作成员属性。


🚩this的扩展作用:

🔥1,this()可以调用自己的构造方法。

classPerson{privateString name;privateint age;publicPerson(){this("xiaowang",20);//this调用自己的构造方法System.out.println("Person<> init");}publicPerson(String name,int age){this.name = name;this.age = age;System.out.println("Person<String,int> init");}@OverridepublicStringtoString(){return"Person{"+"name='"+ name +'\''+", age="+ age +'}';}}publicclassTestDemo220507{publicstaticvoidmain(String[] args){Person per1 =newPerson();System.out.println(per1);}}

程序运行截图:
在这里插入图片描述

可以看到,我们在构造方法 Person() 里面调用了构造方法 Person(String name,int age),但是要注意,这个只能用在构造方法里面,并且只能写在第一行,也只能调用一次。


🔥2,this.成员名 ,可以调用当前对象的属性。

🔥3,this.方法名 , 可以调用当前对象的方法。


🌕7,绝大多数情况下使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)。


🌈八,代码块

🌟8.1,代码块的概念及其分类

使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:
1,普通代码块(就是定义在方法里面,用{}括起来的部分,比较少见,没什么意义)
2,构造块
3,静态块
4,同步代码块(后续讲解多线程部分再谈)


🌟8.2,构造代码块(实例代码块)

构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。

classStudent{privateString name;privateint age;{//实例代码块this.name ="xiaowang";this.age =10;}publicStudent(){System.out.println("Student<init>");}@OverridepublicStringtoString(){return"Student{"+"name='"+ name +'\''+", age="+ age +'}';}}publicclassTestDemo220507{publicstaticvoidmain(String[] args){Student stu =newStudent();System.out.println(stu);}}

程序运行截图:

在这里插入图片描述

可以看到,实例代码块定义在类中,并且可以用来对实例成员变量进行初始化。


🌟8.3,静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

classStudent{privatestaticString name;privatestaticint age;static{//静态代码块,初始化静态成员变量
        name ="xiaowang";
        age =10;}publicStudent(){System.out.println("Student<init>");}@OverridepublicStringtoString(){return"Student{"+"name='"+ name +'\''+", age="+ age +'}';}}publicclassTestDemo220507{publicstaticvoidmain(String[] args){Student stu =newStudent();System.out.println(stu);}}

程序运行截图:

在这里插入图片描述


🌟8.4,实例代码块与静态代码块的初始化循序

classPerson{privateString name;privateint age;{System.out.println("这是一个实例代码块!");}static{System.out.println("这是一个静态代码块!");}publicPerson(){//构造方法System.out.println("Person<> init");}}publicclassTestDemo220507{publicstaticvoidmain(String[] args){Person per1 =newPerson();System.out.println("=========================");Person per2 =newPerson();}}

程序运行截图:

在这里插入图片描述

通过我们的运行结果可以看出,我们的静态的内容(方法,变量)都是类的属性,因此是在JVM加载类时开辟空间并执行初始化的,所以所有的静态的内容一定是最先初始化的,所以我们可以看到输出最先是输出的 “这是一个静态代码块”,当静态的内容初始化完了后,在进行创建对象的时候就会初始化我们的实例代码块,这个时候已经为对象开辟了空间,这也就是为什么在实例代码块里面可以用this对实例成员赋值,而静态的代码块里面不能用this对实例成员赋值了,因为静态代码块初始化的时候对象的空间都没开辟,实例成员又是属于对象的。并且通过运行截图,可以得知实例代码块的初始化也是在我们的构造方法之前的执行的。上面的代码里面我们new了两个对象,但是静态代码块只初始化了一次,说明无论构造多少个对象,对于静态的代码块而言,他只初始化一次。


总结,对于一个类而言,它里面的内容的执行顺序大概是:

在这里插入图片描述


🚩上面阐述了静态的内容都是最先初始化的,但是有多个静态的代码块,或者说静态的代码块与静态的成员之间又是怎样的顺序呢?其实对于这个就没有很多弯弯绕绕了,就是看谁写在前面,就先初始化谁。

classPerson{privateString name;privateint age;static{//静态代码块
        count =100;System.out.println("这是一个静态代码块!");}publicstaticint count =0;//静态成员变量}publicclassTestDemo220507{publicstaticvoidmain(String[] args){System.out.println(Person.count);}}

程序运行截图:

在这里插入图片描述

可以看到,我们将静态的代码块写在前面,他就会先初始化静态代码块的内容,后面才初始化静态的成员变量,所以最终count的值是0,而不是100。


今天的分享就到这里了,如果大家觉得不错的话,还请帮忙点点赞咯,十分感谢呢!🥰🥰🥰
在这里插入图片描述

标签: java

本文转载自: https://blog.csdn.net/qq_61688804/article/details/124636789
版权归原作者 影子,你陪着我累吗? 所有, 如有侵权,请联系我们删除。

“Java类和对象(接上篇博文)”的评论:

还没有评论