• 【JavaSE】类与对象(下)this引用是什么?构造方法是什么?


    this引用的介绍

    在上一篇的类与对象的介绍中,我们了解了什么是对象,什么是类,类就是对一个实际存在的事物的描述,类实例化出来的东西我们称为对象。那么今天我们介绍的这个关键字this他的作用是什么呢?我们先来看一段代码:

    public class Person {
        public String name;
        public int age;
    
        public void setDate(String n,int a) {
            name = n;
            age = a;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    首先我们创建一个人类,类里面有两个成员变量为名字和年龄,有两个方法setDate show用来给成员变量赋值和打印成员变量。

    public class Test {
        public static void main(String[] args) {
            Person p = new Person();
            p.setDate("张三",18);
            p.show();
    
            Person p2 = new Person();
            p.setDate("李四",20);
            p.show();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    现在我们使用new关键字,实例化了两个Person类的对象,p和p2,我们通过对象调用成员方法,进行赋值和打印
    在这里插入图片描述

    但是我们有一个疑问了,我们实例化了两个对象,两个对象都在调用show setDate方法,我们没有给出任何说明,show setDate怎么知道打印的是那个对象的数据呢?其实每个成员方法都有一个隐藏的参数DateUtil this,这个this引用指向了当前对象(这个对象是成员方法运行时,调用该成员方法的对象)。
    我们再来看一个例子:

    public class Person {
        public String name;
        public int age;
    
        public void setDate(String name,int age) {
            name = name;
            age = age;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们看setDate这个成员方法,我们将参数不小心写的与成员变量名字相同了。这时候还可以正常给成员变量赋值嘛?
    在这里插入图片描述
    我们看并没有打印我们赋值的数据,这是为什么呢?
    在这里插入图片描述
    如何解决这个问题呢?我们就可以使用我们的this引用。

    public class Person {
        public String name;
        public int age;
    
        public void setDate(String name,int age) {
            this.name = name;
            this.age = age;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这样我们就可以给成员变量赋值了,因为我们上面说过了,this是一个引用,他指向了调用该成员方法的对象,所以我们通过这个this引用去访问成员变量时,访问的就是调用该方法的对象的成员变量,就可以区分出成员变量和形参,完成我们的赋值。

    this引用总结

    好了经过上面的介绍我们可以对this进行一个简单的总结:

    1、this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
    2、this只能在成员方法中使用
    3、在成员方法中,this只能引用当前对象,不能在引用其他对象。

    构造方法

    在之前的学习中我们肯定知道,一个局部变量在使用时必须初始化,如果不进行初始化,编译时就会报错。那么这个变量如果是成员变量呢?在上面的例子当中我们写了这样一个代码:

    public class Person {
        public String name;
        public int age;
    
        public void setDate(String name,int age) {
            this.name = name;
            this.age = age;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class Test {
    
        public static void main(String[] args) {
            Person p = new Person();
            p.show();
            p.setDate("张三",19);
            p.show();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们创建了一个人类,并且实例化了一个对象p,实例化后我们直接调用show方法来打印成员变量,通过对象调用setDate成员方法为成员变量赋值后再次打印,我们来看看你我们的执行结果。
    在这里插入图片描述
    通过这个例子我们会有两个疑问:

    1、每次实例化对象后,需要调用setDate方法才可以给成员变量赋值,太麻烦,可不可以在实例化对象时直接赋值呢?
    2、局部变量必须初始化才能使用,但成员变量我们在实例化对象后可以直接打印,这是为什么呢?

    首先我们来回答第一个问题,我们可以在实例化对象的时候给成员变量赋值,需要调用我们的构造方法。什么是我们的构造方法呢?构造方法没有返回值,方法名和类名是一样的

    public class Person {
        public String name;
        public int age;
        
        public Person () {//无参的构造方法
            
        }
    
        public void setDate(String name,int age) {
            this.name = name;
            this.age = age;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    public Person就是Person类里的无参构造方法注意:当我们没有写任何构造方法的时候,Java会帮助我们提供一个默认的无参的构造方法。有的兄弟就会问了你这无参的构造方法有啥用,也不能实现我在实例化时就给成员变量赋值的需求啊,各位稍安勿躁,既然有无参的构造方法,那么就肯定有有参的构造方法。

    public class Person {
        public String name;
        public int age;
    
        public Person () {//无参的构造方法
    
        }
        public Person(String name,int age ) {//有参的构造方法
            this.name = name;
            this.age = age;
        }
    
        public void setDate(String name,int age) {
            this.name = name;
            this.age = age;
        }
    
        public void show (){
            System.out.println("name " + name + " age " + age);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    public Person(String name,int age )这样我们就创建了一个有参的构造方法,在我们实例化对象时就可以给成员变量赋值了。

      public static void main(String[] args) {
            Person p = new Person("张三",20);
            p.show();
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    有的同学又会问了:你怎么证明 当我们没有写任何构造方法的时候,Java会帮助我们提供一个默认的无参的构造方法。我们来看当我们写了一个有参的构造方法之后,在实例化对象时我们不进行赋值会发生什么?
    在这里插入图片描述
    因为我们没写无参构造方法且自己写了有参的构造方法,Java不会提供无参的构造方法了,所以我们的程序就会报错了,自己写一个无参构造方法后解决了问题。其实我们仔细观察一下,有参与无参的构造方法是什么?是不是就是重载,他们的方法名相同,参数不同,构造方法也是可以互相调用的,使用this()就可以实现。这样我们的第一个问题就解决了。
    下面我们来看第二个问题,为什么成员变量可以不用赋值直接打印?答案是在实例化对象中,我们为对象分配内存空间之后,会初始化所分配的空间,即对象空间被申请好之后,对象中包含的成员已经设置好了初始值

    类型默认值
    byte0
    short0
    int0
    long0L
    float0.0f
    double0.0
    char/u0000
    booleanfalse
    referencenull

    在这之后我们会调用构造方法,给对象中各个成员赋值。

    构造方法总结

    构造方法的特性:

    1、名字必须跟类名相同 
    2、没有返回值类型,不可以写void
    3、创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(可以类比于一个人只出生一次)
    4、构造方法可以重载,比如有参构造方法,无参构造方法
    5、没有写构造方法时Java会默认提供一个无参的构造方法,但当写了任何构造方法时,Java不会给你提供无参构造方法了

  • 相关阅读:
    servlet数量太多,搞个轻量级springmvc
    无涯教程-JavaScript - IMDIV函数
    【工具】数据标注-VOTT
    数据改版 | CnOpenData中国高新技术企业专利统计数据
    Ubuntu1804.5安装后的基本配置
    <源码探秘CPython>-读懂Python解释器必须要会的C语言知识
    【正点原子STM32连载】第五十七章 USB读卡器(Slave)实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
    深入探索Stable Diffusion:从原理到应用的全面解析
    verilog 移位操作符
    HTB-Tier2- Archetype
  • 原文地址:https://blog.csdn.net/weixin_64182409/article/details/127782009