【Java学习—(8)类和对象(构造方法、this关键字、代码块、toString)下 】又是不看后悔的一天哦

本文详细介绍了Java中的构造方法,包括其作用、语法和构造方法的重载。同时,深入讲解了this关键字的用法,如调用成员变量、调用方法以及表示当前对象引用。此外,还探讨了代码块的概念,特别是成员代码块和静态代码块的执行时机。最后,提到了toString方法在打印对象信息时的重要性。
摘要由CSDN通过智能技术生成

前面的章节知识(点击跳转即可哦)

1 数据类型

2 类型转换

3 运算符

4 逻辑控制

5 输入输出

6 方法的使用

方法递归

7 数组的定义与使用

8 类和对象 -上



8 类和对象 - 下

8.6 构造方法

构造方法:构造方法是类中非常特殊的一类方法,使用关键字new实例化对象时,实际上就调用的是该类的构造方法

构造方法的作用就是产生对象。


使用关键字new产生一个对象时,大致分为以下两步

  1. 为对象在堆中分配空间,
  2. 调用对象的构造方法为成员变量进行赋值

(成员变量的默认值就是在构造方法在赋值的)

若成员变量初始化,程序在走到构造方法这步时,先赋值成员变量的默认值,再进行他们的初始化,然后进入构造方法内部。(可以具体在IDEA中具体调试跑一下)


构造方法的语法规则

  1. 方法名称与类名称完全相同
  2. 构造方法没有返回值声明(也没有void)
  3. 一个类中至少存在一个构造方法,若没有显示定义,编译器会生成一个默认的无参构造

来看代码:

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的作用:

  1. 调用当前对象的成员变量

  2. 调用当前对象的方法

    ​ ——调用普通成员方法

    ​ ——构造方法的互相调用

  3. 表示当前对象的引用

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@1540e19d
ClassesAndObjects.Person@1540e19d

ClassesAndObjects.Person@677327b6
ClassesAndObjects.Person@677327b6

8.8 代码块

代码块指的是使用 {}括起来的一段代码,称为代码块。

根据定义的代码块的位置以及关键字的不同分为一下四种代码块:

  1. 普通代码块,定义在方法中,使用{}括起来的代码块
  2. 成员代码块,定义在类中,使用{}括起来的代码块,也叫构造块
  3. 静态代码块
  4. 同步代码块,在多线程中会提到

成员代码块(构造块)

构造块:直接定义在类中,不加任何修饰符的代码块,优先于构造方法执行,有几个对象产生,就调用几次构造块。


静态代码块

定义在类中,使用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()方法。


要是对大家有所帮助的话,请帮我点个赞吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值