目录
一、关键字this
this是什么
我们先来介绍一下this是什么:this是一个关键字,用于引用当前对象实例。它在类的方法或构造方法中使用,指向调用该方法或构造器的对象实例,简单来说this是用来确认调用方法的对象是谁,调用的对象是谁this就指向谁----我们来解释一下这句话。接下来我们用代码来演示一下:
public class Main { public static void main(String[] args) { //创建三个对象date1、2、3, Date date1 = new Date(); Date date2 = new Date(); Date date3 = new Date(); //三个对象调用setDate方法,传了三个整型参数 date1.setDate(2000,03, 15); date2.setDate(2010,04, 16); date3.setDate(2020,05, 17); //三个对象都调用printDate方法 date1.printDate();//猜一下输出的是什么? date2.printDate();//预期输出传入的值 date3.printDate(); } } //定义一个Date类 class Date { //三个成员变量年、月、日 public int year; public int month; public int day; //成员方法setDate用来给成员变量赋值 public void setDate(int year, int month, int day) { year = year; month = month; day = day; } //输出打印一下日期类Date public void printDate() { System.out.println(year + "--" + month + "--" + day); } }
输出结果:
有没有发现一个问题呢----输出结果跟我们预期的结果不太一样----明明已经调用了setDate方法了为什么没有赋值成功呢?我们在来看一段代码:
public class Main { public static void main(String[] args) { //创建三个对象date1、2、3, Date date1 = new Date(); Date date2 = new Date(); Date date3 = new Date(); //三个对象调用setDate方法,传了三个整型参数 date1.setDate(2000,03, 15); date2.setDate(2010,04, 16); date3.setDate(2020,05, 17); //三个对象都调用printDate方法 date1.printDate();//猜一下输出的是什么? date2.printDate(); date3.printDate(); } } //定义一个Date类 class Date { //三个成员变量年、月、日 public int year; public int month; public int day; //成员方法setDate用来给成员变量赋值 public void setDate(int y, int m, int d) { year = y; month = m; day = d; } //输出打印一下日期类Date public void printDate() { System.out.println(year + "--" + month + "--" + day); } }
输出结果:
可以看出这次的输出结果跟我们预想中的结果是一样的-----两段代码唯一不一样的地方改动形参的名称----输出的结果却截然不同----我们来对比一下两个方法:
导致这样的原因是什么呢?----代码中跟我们预期结果不一样是因为setDate方法中参数名和成员变量名相同,setDate方法分不清楚接收的值是成员变量里面的值还是参数的值--搞不清调用它的对象是谁---最后按照就近原则--优先调用自己有的--把自己给自己,也就是说没有被赋值,还是默认值---接下来我们再来看一段代码:
public class Main { public static void main(String[] args) { //创建三个对象date1、2、3, Date date1 = new Date(); Date date2 = new Date(); Date date3 = new Date(); //三个对象调用setDate方法,传了三个整型参数 date1.setDate(2000,03, 15); date2.setDate(2010,04, 16); date3.setDate(2020,05, 17); //三个对象都调用printDate方法 date1.printDate();//猜一下输出的是什么? date2.printDate(); date3.printDate(); } } //定义一个Date类 class Date { //三个成员变量年、月、日 public int year; public int month; public int day; //成员方法setDate用来给成员变量赋值 public void setDate(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } //输出打印一下日期类Date public void printDate() { System.out.println(this.year + "--" + this.month + "--" + this.day); } }
输出结果:
观察代码和结果会发现----这段跟前面代码中唯一的不同在于----多出了this这个东东---但是我们得到了我们预期想要的结果----这是为什么呢?---想来你已经明白了其中的关键点this---这也就是我们this的作用---可以确定是哪个对象调用的setDate方法并且把值正确的给我们想要的结果---this是怎么确定对象的呢?-----这就是我们接下来要讲的~
我们来看一个图片:
观察图片内容环节----在图片中我们可以看出每次调用的时候this的值都跟它所对应的调用对象一样----至于Date@xxx可以理解为Java内部的标识符用来分辨对象---得出结论this引用的 是它调用它的对象-- -最后我们来说一下this的使用时需要注意的地方:
- this只能在"成员方法"中使用
- this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
- 我们有关this的讲解就暂时告一段落了~
二、对象的构造和初始化(构造方法)
默认初始化
对象的初始化---我们都知道在Java中一个变量如果没有进行初始化设置---会发生编译错误--如下代码:
那如果把a和b换成实例化对象会发生什么呢?---我们继续来看:
看图环节-----创建两个类A和B设置两个成员变量----实例化两个对象a和b-----不太清楚的可以去看看Java之面向对象(1.1.4类和对象)-优快云博客----发现成员变量a和b明明没有初始化为什么没有出现编译报错----为什么会输出0--这里我们就来简单介绍一下原因:
- 主要原因是在Java中创建一个实例化对象时,如果对象类里面的成员变量没有初始化会默认给成员变量初始化------以下是不同类型的初始默认值:
构造初始化
上面的是默认初始化----那还有什么初始化呢-----接下来我们介绍如何用构造方法来初始化的-----构造方法的概念:
构造方法(也称为构造器)是一个特殊的成员方法: 名字与类名相同,没有返回值类型,设置为void也不行 一般情况下使用public修饰 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
接下来我们就来介绍一下构造方法的怎么使用和怎么创建的---我们先观看一段简单的代码和输出结果:A a = new A();//创建两个实例化对象 B b = new B(); System.out.println(a.a); System.out.println(b.b); } } class A { public int a; public A() { a = 10; System.out.println("这是A的构造方法"); } } class B { public int b; public B() { b = 20; System.out.println("这是B的构造方法"); }
输出结果:
观察代码和图片我们可以发现-----我们明明没有调用构造方法A和B,但却输出了两个构造方法里面的文字----同时a和b的值也改变了-----这是为什么呢?------接下来就让我们一起来分析一下吧------关键点就在于---请看下图:
这就是构造方法的初始化----在创建对象时就会执行构造方法初始化----同时构造方法也可以有多个,接下来我们继续来看代码示例和执行结果:
A a1 = new A();// A a2 = new A(10); A a3 = new A(10,20); } } class A { public int a; public A() { a = 10; System.out.println("这是A的构造方法"); } public A(int a) { System.out.println("这是带有一个参数的构造方法"); } public A(int a, int b) { System.out.println("这是带有两个参数的构造方法"); }
执行结果:
分析环节-----代码的结果跟我们预期的一样输出打印了多个构造方法里面的内容----满足什么条件才能创建多个构造方法呢?------根据上面的代码可以看出三个构造方法只有参数列表不同----其它都是相同的----构成了方法的重载----如果不知道什么是重载的话可以去看看Java基本语法1.1.0(方法与递归)-优快云博客------接下来我们在来了解一下this在构造方法中的使用----代码示例环节:
public A() { this(30); System.out.println("----------------------------------"); a = 10; System.out.println("这是A的构造方法"); } public A(int a) { //this(10,20); System.out.println("----------------------------------"); System.out.println("这是带有一个参数的构造方法"); } public A(int a, int b) { //System.out.println("----------------------------------"); System.out.println("这是带有两个参数的构造方法"); }
输出结果:
- 先执行了this()调用了带有一个参数的构造方法
- 然后按顺序输出打印构造函数
可以多重调用-----但不能互相调用----this(...)必须是构造方法中第一条语句----我们来看下面的图片就可以发现:
多重调用-----正常执行
互相调用------报错了
- this在构造方法中的主要作用就是使代码更加简洁一些----提高可读性----如:
public A() { this(30); //System.out.println("这是不带参数的构造方法"); } public A(int a) { this(10,20,30,40); //System.out.println("这是带有一个参数的构造方法"); } public A(int a, int b,int c, int d) { this.a = a; this.b = b; this.c = c; this.d = d;
就地初始化
- 讲到这里我们的构造方法初始化也来到了尾声----一般来说初始化都是用构造方法来初始化但也有例外-----那就是就地初始化----接下来我们来个代码示例:
class A { public int a = 10;//在创建成员变量时直接赋值 public int b = 20;//就是就地初始化 public int c = 30; public int d = 40;
三、总结