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

在这里插入图片描述

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

在这里插入图片描述

🌈七,构造方法

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

答案是会经过两步:

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

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

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


🌟7.1,构造方法的概念

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

在这里插入图片描述

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


🌟7.2,构造方法的特性

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

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

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

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

class Person{
    private String name;
    private  int age;

    public Person(){
        System.out.println("Person<> init");
    }
    public Person(String name,int age){
        this.name = name;
        this.age = age;
        System.out.println("Person<String,int> init");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TestDemo220507 {
    public static void main(String[] args) {
        Person per1 = new Person();//它会去调用无参的那个构造方法
        System.out.println(per1);
        System.out.println("=========================");
        Person per2 = new Person("xiaowang",20);//它会去调用有参的那个构造方法
        System.out.println(per2);
    }
}

程序运行截图:

在这里插入图片描述

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


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

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

在这里插入图片描述

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


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

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

在这里插入图片描述

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

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


🚩this的扩展作用:

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

class Person{
    private String name;
    private  int age;

    public Person(){
        this("xiaowang",20);//this调用自己的构造方法
        System.out.println("Person<> init");
    }
    public Person(String name,int age){
        this.name = name;
        this.age = age;
        System.out.println("Person<String,int> init");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TestDemo220507 {
    public static void main(String[] args) {
        Person per1 = new Person();
        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,构造代码块(实例代码块)

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

class Student{
    private String name;
    private int age;
    {//实例代码块
        this.name = "xiaowang";
        this.age = 10;
    }
    public Student(){
        System.out.println("Student<init>");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TestDemo220507 {
    public static void main(String[] args) {
        Student stu = new Student();
        System.out.println(stu);
    }
}

程序运行截图:

在这里插入图片描述

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


🌟8.3,静态代码块

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

class Student{
    private static String name;
    private static int age;
    static{//静态代码块,初始化静态成员变量
        name = "xiaowang";
        age = 10;
    }
    public Student(){
        System.out.println("Student<init>");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TestDemo220507 {
    public static void main(String[] args) {
        Student stu = new Student();
        System.out.println(stu);
    }
}

程序运行截图:

在这里插入图片描述


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

class Person{
    private String name;
    private  int age;
    {
        System.out.println("这是一个实例代码块!");
    }
    static{
        System.out.println("这是一个静态代码块!");
    }

    public Person(){//构造方法
        System.out.println("Person<> init");

    }
}
public class TestDemo220507 {
    public static void main(String[] args) {
        Person per1 = new Person();
        System.out.println("=========================");
        Person per2 = new Person();
    }
}

程序运行截图:

在这里插入图片描述

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


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

在这里插入图片描述


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

class Person{
    private String name;
    private  int age;
    static{//静态代码块
        count = 100;
        System.out.println("这是一个静态代码块!");
    }
    public static int count = 0;//静态成员变量
}
public class TestDemo220507 {
    public static void main(String[] args) {
        System.out.println(Person.count);
    }
}

程序运行截图:

在这里插入图片描述

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


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

  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学习.java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值