【Java学习—类和对象(构造方法、this关键字、代码块、toString)下 】又是不看后悔的一天哦
前面的章节知识(点击跳转即可哦)
1 数据类型
2 类型转换
3 运算符
4 逻辑控制
5 输入输出
6 方法的使用
方法递归
7 数组的定义与使用
8 类和对象 -上
文章目录
- 8 类和对象 - 下
-
- 8.6 构造方法
-
- 8.6.1 构造方法重载
- 8.7 this 关键字
-
- 8.7.1 this-调用当前对象的成员变量
- 8.7.2 this-调用类中的方法
- 8.7.3 this-表示当前对象的引用
- 8.8 代码块
- 8.9 toString 方法
8 类和对象 - 下
8.6 构造方法
构造方法:构造方法是类中非常特殊的一类方法,使用关键字new实例化对象时,实际上就调用的是该类的构造方法
构造方法的作用就是产生对象。
使用关键字new产生一个对象时,大致分为以下两步:
- 为对象在堆中分配空间,
- 调用对象的构造方法为成员变量进行赋值
(成员变量的默认值就是在构造方法在赋值的)
若成员变量初始化,程序在走到构造方法这步时,先赋值成员变量的默认值,再进行他们的初始化,然后进入构造方法内部。(可以具体在IDEA中具体调试跑一下)
构造方法的语法规则:
- 方法名称与类名称完全相同
- 构造方法没有返回值声明(也没有void)
- 一个类中至少存在一个构造方法,若没有显示定义,编译器会生成一个默认的无参构造
来看代码:
package ClassesAndObjects;public class Test { public static void main(String[] args) { Card card = new Card(); }}class Card{ private int cardNum = 123456; //卡号 private double money = 214.4; //余额 private String passworfd = "123"; //密码 //构造方法 //方法名称要和类名称完全相同 //无返回值 public Card(){ System.out.println("构造方法"); }}
输出结果:
构造方法
在主方法中只写了一行对象 的创建,就输出了 构造方法
的内容。说明使用关键字new产生一个对象时,构造方法就会执行。
当类中自定义了构造方法,则默认的无参构造就不再生成。
看代码:
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per = new Person(); Person per1 = new Person("男"); }}class Person{ int a; String name; public Person(String sex){ name = "张三"; System.out.println(name + "的性别是" + sex); }}
程序在编译时,第五行就报错,执行后提示
自定义构造方法
后,此时默认的默认无参构造就没有了
8.6.1 构造方法重载
构造方法是为了类中的成员变量赋值的(成员变量的类型在类定义的时候就指定好了),此时的重载只可能是参数个数的不同(为不同的成员变量赋值)。个数不同并不是说只能一个参数个数为1的构造方法,而是在存在的几个成员变量中去挑选不同的一个
比如:
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per1 = new Person("男"); Person per2 = new Person(18); }}class Person{ String name = "张三"; int age; String sex; public Person(String sex){ this.sex = sex; System.out.println(name + "的性别是" + sex); } public Person(int age) { this.age = age; System.out.println(name + "的年龄是"+ age); }}
输出结果:
张三的性别是男张三的年龄是18
8.7 this 关键字
this
关键字:表示当前对象的引用
this
的作用:
-
调用当前对象的成员变量
-
调用当前对象的方法
——调用普通成员方法
——构造方法的互相调用
-
表示当前对象的引用
8.7.1 this-调用当前对象的成员变量
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per2 = new Person(18); System.out.println(per2.age); }}class Person{ String name = "张三"; int age; String sex; public Person(int age) { //形参 age = age; System.out.println(age + "有参构造"); }}
输出结果是:
18有参构造0
此时就会有一个问题,为什么构造方法中的age
是18,而成员变量age
是它的默认值0?
在程序的设计理念中(不止Java,还有C、C++、go、Python),就近匹配原则。编译器会找最近的相同名称的变量在哪。
public Person(int age) { //形参 age = age; System.out.println(age + "有参构造"); }
在这段代码中,age = age
找到的变量并不是成员变量,而是构造方法传入的形参,和成员变量没有任何关系。
所以在输出结果时,构造方法内部的age是18.通过对象调用的成员变量age是0。
所以如何打破就近匹配原则,从类中找到成员变量呢?
那就是使用this
关键字,它的第一个作用:调用当前对象的成员变量。
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per2 = new Person(18); System.out.println(per2.age); }}class Person{ String name = "张三"; int age; String sex; public Person(int age) { this.age = age; //加上this,表示调用成员变量 System.out.println(age + "有参构造"); }}
此时的输出结果:
18有参构造18
8.7.2 this-调用类中的方法
调用类中的成员方法
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per = new Person(); per.tests(); }}class Person{ String name = "张三"; int age; String sex; public void test(){ System.out.println("进入test方法"); } public void tests(){ test(); // 不加this this.test(); //加了this System.out.println("进入tests方法"); }}
输出结果:
进入test方法进入test方法进入tests方法
从代码中可以看出来,调用类中的成员方法,写不写this都一样,因为不写的话,编译器编译之后会默认加this
。
this 表示构造方法间的相互调用
public Person(String name) { System.out.println("--------------"); this.name = name; } public Person(String name, int age) { System.out.println("--------------"); this.name = name; this.age = age; } public Person(String name, int age, String sex) { System.out.println("--------------"); this.name = name; this.age = age; this.sex = sex; }
代码中可以看到,不同参数的构造方法之间出现了重复的调用,那么这个时候就可以使用this(参数)
调用其他的构造方法。
-
this 调用其他的构造方法必须放在当前构造方法的首行。
-
this 调用构造方法不能成”环“。(就是这样规定的)
public Person(String name) { System.out.println("--------------------"); this.name = name; } public Person(String name, int age) { this(name); this.age = age; } public Person(String name, int age, String sex) { this(name,age); this.sex = sex; }
这两个代码的功能是相同的,但是在代码的简洁上却不同。
8.7.3 this-表示当前对象的引用
在这里 this 就像是一面镜子,this在哪个对象里,this就代表这个对象。
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { Person per = new Person(); System.out.println(per); //打印的是引用类型的地址 per.who(); //打印this System.out.println(); Person per1 = new Person(); System.out.println(per1); per1.who(); }}class Person{ String name = "张三"; int age; String sex; public void who(){ System.out.println(this); }}
输出结果:
ClassesAndObjects.Person@1540e19dClassesAndObjects.Person@1540e19dClassesAndObjects.Person@677327b6ClassesAndObjects.Person@677327b6
8.8 代码块
代码块指的是使用 {}括起来的一段代码,称为代码块。
根据定义的代码块的位置以及关键字的不同分为一下四种代码块:
- 普通代码块,定义在方法中,使用{}括起来的代码块
- 成员代码块,定义在类中,使用{}括起来的代码块,也叫构造块
- 静态代码块
- 同步代码块,在多线程中会提到
成员代码块(构造块)
构造块:直接定义在类中,不加任何修饰符的代码块,优先于构造方法执行,有几个对象产生,就调用几次构造块。
静态代码块
定义在类中,使用static 修饰的代码块,在类加载的时候执行一次,与对象无关,无论产生多少对象,静态代码块只在类加载的时候执行一次。
package ClassesAndObjects;public class Test4_15 { static { System.out.println("进入主类的静态代码块"); } public static void main(String[] args) { System.out.println("进入主方法"); }}
输出结果:
进入主类的静态代码块进入主方法
这段代码说明:静态代码块在加载主类的时候执行,优先于主方法(静态方法)。
JVM要执行主方法,首先要加载主类,主类加载时静态块就执行了
注意:
类中的静态变量表示类的属性,存在于方法区中,类定义的时候类的属性就已经有了,放在了方法区。这个时候,类只是定义了,还没有进行加载。
8.9 toString 方法
匿名对象: new 出来的对象,没有引用指向,使用一次后就销毁
new Person(); (Person() 表示一个类)
匿名对象常用于测试类中的某些功能,使用一次后就销毁
toString 方法, 一定要注意大小写。
当一个引用类型的变量调用println函数打印时,默认输出的都是引用类型的地址,(不是真正的内存地址,Java中程序员是无法知道任何确切
的内存地址。)
package ClassesAndObjects;public class Test4_15 { public static void main(String[] args) { System.out.println(new Person()); }}class Person{ String name; int age; String sex; public Person(){ System.out.println("无参构造"); }}
输出结果:
无参构造ClassesAndObjects.Person@1540e19d
我们调用打印函数打印一个引用的时候,大概率是打印这个对象具体的属性值内容。就是实现toString();
快捷键:右键点击Generate
(按下Alt+insert) -> 点击toString()
即可,设置toString()方法。
要是对大家有所帮助的话,请帮我点个赞吧。
创作挑战赛
新人创作奖励来咯,坚持创作打卡瓜分现金大奖