【JavaSE】初识类和对象——this引用、构造方法

目录

1 面向对象的基本认识

        1.1  什么是面向对象

        1.2 面向对象和面向过程

2 类的定义和使用

        2.1 简单认识类

3. 类的实例化——对象

        3.1 什么是实例化

        3.2 类和对象的说明

4. this 引用

        4.1 为什么要用 this 引用

        4.2 什么是 this 引用

        4.3 总结一下this的特性

5. 对象的构造和初始化

        5.1 对象的初始化与局部变量的初始化

        5.2 构造方法

                5.2.1 什么是构造方法

                5.2.2 构造方法中的 this 引用

                5.2.3 构造方法的重载

        5.3 默认初始化

        5.4 就地初始化


1 面向对象的基本认识

1.1  什么是面向对象

Java 是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。

1.2 面向对象和面向过程

面向过程和面向对象都是解决问题的思考方式。

面向过程(Procedure Oriented Programming, POP)是以“过程”为中心的,遇到问题时,想的是解决问题的步骤,然后用函数把步骤一一实现,最后再依次调用。面向过程更侧重于“怎么做”,以执行者的角度思考问题,比较适合解决小型问题或底层问题。


面向对象(Object Oriented Programming, OOP)以“对象”为中心,遇到问题时,想的是需要哪些对象一起来解决问题,然后找到这些对象,并把它们组织在一起,然后取各家之所长来共同解决一个问题。面向对象更侧重于“谁来做”,以指挥者的角度思考问题,比较适合解决中大型问题。

拿洗衣服举例。如果一个人选择手洗衣服,那他就是面向过程:拿个盆子——接一盆水——放衣服——放洗衣粉——搓衣服——拧干衣服——倒水——再接一盆水——衣服过水——拧干——倒水——晾衣服。但如果一个人选择用洗衣机来洗衣服,那他就是面向对象。总共 4 个对象:人,衣服,洗衣粉,洗衣机。人要做的就是把衣服放进洗衣机里,倒点洗衣粉,启动洗衣机。等洗衣机洗好了,拿去晾就可以了。整个过程是人,衣服,洗衣粉,洗衣机交互完成的,人并不需要操心洗衣机是如何清洗的。

注意:面向过程和面向对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景

2 类的定义和使用

将客观世界中存在的一切可以描述的事物称为对象(实体),也就是“万物皆对象”。这些众多的对象有些是有相同的属性和功能(或行为)的,按照属性和功能(或行为)等对它们进行分类、抽象,就形成了概念世界中的类。类实际上就是根据生活经验总结抽取出来的产物,相当于一组对象的类型。

类是抽象的,对象是具体的,类相当于创建对象的蓝图。例如汽车,类与对象的关系就如汽车设计图与汽车实物的关系。面向对象的程序实现需要通过类创建对应的实例化对象,来对应客观世界中的实体。

2.1 简单认识类

在有对象之前,我们得先有类。类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干 啥),描述完成后计算机就可以识别了。

比如:洗衣机,在Java中可以将其看成是一个类别。

属性:产品品牌,型号,产品重量,外观尺寸,颜色,价格......

功能:洗衣,烘干、定时......

类的声明:

​​​​​​​类可以包含3种最常见的成员,即属性、构造器、方法,3种成员可以定义为0个或多个,如果3种成员都定义为0个,那么就相当于一个空类,语法上没问题,但是没有实际意义。当然类的成员除了这3种,还有内部类和代码块,这些在后续章节中会讲到。类中各个成员的排列顺序是随意的,但是习惯上人们会按照属性、构造器、方法的顺序去定义。

在 Java 中定义类时需要用到 class 关键字,具体语法如下:

//定义类

class 类名{

    field; // 字段(属性) 或者 成员变量,通常多个属性

    method; // 行为 或者 成员方法,通常多个方法

}

拿洗衣机举例:

class WashMachine{
    //洗衣机的属性
    public String brand; //品牌
    public String color; //颜色
    public String type; //型号
    public String weight; //重量
    public String length; //长
    public String width; //宽
    public String heigth;  //高

    //洗衣机的功能
    public void washClothes(){
        System.out.println("洗衣服");
    }
    public void dryClothes(){
        System.out.println("烘干衣服");
    }
}

注意事项:

1. 类名注意采用大驼峰定义

2. 成员前写法统一为 public

3. 此处写的方法不带 static 关键字 

4. 一般一个文件当中只定义一个类

5. main 方法所在的类一般要使用 public 修饰

6. public 修饰的类必须要和文件名相同,不要轻易去修改 public 修饰的类的名称,如果要修改,通过开发工具修改

3. 类的实例化——对象

3.1 什么是实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,与 int,double 类似,只不过 int 和double 是 Java 语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的WashMachine 类。

用 类 类型创建对象的过程,称为类的实例化,在 Java 中采用 new 关键字,配合类名来实例化对象。

    public static void main(String[] args) {
        WashMachine machine1 = new WashMachine();
        machine1.brand = "haiEr";
        machine1.color = "Yellow";
        System.out.println(machine1.brand + " " + machine1.color);
        machine1.washClothes();
        machine1.dryClothes();

    }

注意:

1. new 关键字用于创建一个对象的实例.

2. 使用 . 来访问对象中的属性和方法.

3. 同一个类可以创建对个实例

3.2 类和对象的说明

1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.

2. 类是一种自定义的类型,可以用来定义变量. 

3. 一个类可以实例化出多个对象,实例化出的对象才占用实际的物理空间,存储类成员变量。

为说明类实例化之后的存储情况,下面创建了一个 Person 类,实例化一个对象 person

class Person{
    public String name;
    public int age;
    public String gender;
    
    public void sayHello(){
        System.out.println("Hello! How do you do!");
    }
    
}

public class Practice {
    Person person = new Person();
}

有同学会问,Person 类里面还有方法 sayHello 呢,怎么没有开辟空间了?是这样子的,方法还未调用之前,只存放于方法区里面,等调用了再分配内存。 

4. this 引用

4.1 为什么要用 this 引用

下面来看一下一个日期的例子

class Date{
    public int year ;
    public int month;
    public int day;

    public void setDate(int y ,int m ,int d){
        year = y;
        month = m;
        day = d;
    }

    public void printDate(){
        System.out.println("年: "+ year + " 月: " + month + " 日: " + day);
    }
}
public class Practice {
    public static void main(String[] args) {
        //类Date实例化三个对象,分别是date1,date2,date3
        Date date1 = new Date();
        Date date2 = new Date();
        Date date3 = new Date();

        //设置日期
        date1.setDate(2022,11,8);
        date2.setDate(2022,11,9);
        date3.setDate(2022,11,10);

        //打印日期
        date1.printDate();
        date2.printDate();
        date3.printDate();
    }
}

 仔细阅读上述代码,我们不难提出以下问题。

三个对象都在调用 setDate 和 printDate 方法,但是这两个方法中没有任何有关对象的说明,setDate 和 printDate 方法如何知道打印的是那个对象的数据呢?

在 main 方法里面,我们可以很清晰地看出,具体哪个对象调用了 setDate 以及 printDate。

可是在成员方法真正执行的时候,方法体 内部根本就没有对象的信息,那么每次执行,setDate 怎么知道给哪个对象设置时间,而 printDate 又是如何知道打印哪个对象的呢?

这就要用到下一小节介绍的 this 引用。

4.2 什么是 this 引用

this 引用指向当前对象(成员方法运行时调用该成员方法的对象)。在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

所以上述日期的例子中的 setDate 方法实际上长这样:

    //Date this 是一个隐藏的参数
    public void setDate(Date this, int y ,int m ,int d){
        year = y;
        month = m;
        day = d;
    }

哪个对象调用 setDate,那么 this 就代表哪个对象的引用。

而对于那个无参数的 printDate 来说,亦是如此:

    public void printDate(Date this){
        System.out.println("年: "+ year + " 月: " + month + " 日: " + day);
    }

只不过在平时使用的时候,并不需要把类名 this 这个隐藏参数写出来。可是在方法体中,却最好在成员变量前,使用 this 。因为这样一来,就算形参与成员变量名一样,编译器依旧可以分辨得出,有 this. 的是成员变量,而没有的,则是形参,也就知道谁给谁赋值了。

所以最好养成在方法体中的成员变量前用 this 的好习惯。

    public void setDate(int year ,int month ,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void printDate(){
        System.out.println("年: "+ this.year + " 月: " + this.month + " 日: " + this.day);
    }

4.3 总结一下 this 的特性

1. this 的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型

2. this 只能在"成员方法"中使用

3. 在"成员方法"中,this 只能引用当前对象,不能再引用其他对象

4. this 是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this 负责来接收

5. 对象的构造和初始化

5.1 对象的初始化与局部变量的初始化

根据前面所学的知识可知,在 Java 方法内部定义一个局部变量时,必须要先初始化,否则会编译失败。比如:

    public static void main(String[] args) {
        int z;
        System.out.println(z);
    }
//未初始化,编译报错!!!!!

但是对比对象的创建,还未对成员变量初始化,调用了 printDate,正常编译:

    public static void main(String[] args) {
        Date day = new Date();
        day.printDate();
    }

 输出 

        年: 0 月: 0 日: 0

为何会如此呢?请看下一小节的讲解:

5.2 构造方法

5.2.1 什么是构造方法

在了解对象是如何初始化之前,我们得先了解一个新的知识,叫构造方法。

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

注意:

构造方法的作用是给对象中的成员进行赋值,并不负责给对象开辟空间。 

如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。

但如果用户自定义了一个含参的构造类型,那么编译器就不再生成默认的构造方法,所以以后每次实例化一个新的对象都必须带参数。

下面是在 Date 类中写入构造方法:

    // 构造方法:
    // 名字与类名相同,没有返回值类型,设置为void也不行
    // 一般情况下使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year , int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

 5.2.2 构造方法中的 this 引用

this 必须放在第一行。

//该构造方法无参   
 public Date(){
        this(1999,6,18);//但这里使用this,便可以调用其他带有三个参数的构造方法
    }

//比如这个:
    public Date(int year , int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

 注意不要过度使用 this,以免造成闭环。比如:

public Date(){
    this(1900,1,1);
}

public Date(int year, int month, int day) {
    this();
}

5.2.3 构造方法的重载

构造方法可以有多个,虽然方法名都一样,但是参数不同,彼此构成重载的关系。具体使用哪个构造方法,视用户输入的参数而定。

    public Date(int year , int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public Date(){
        this.year = 1998;
        this.month = 8;
        this.day = 9;
    }

5.3 默认初始化

在这里就可以回答 5.1 节提出的问题了。而这一切与 new 关键字有关。

Date d = new Date(2022, 11, 10);

在程序层面只是简单的一条语句,在 JVM 层面需要做好多事情,下面简单介绍下:

1. 检测对象对应的类是否加载了,如果没有加载则加载

2. 为对象分配内存空间

3. 处理并发安全问题

     比如:多个线程同时申请对象,JVM 要保证给对象分配的空间不冲突

4. 初始化所分配的空间,即:对象空间被申请好之后,对象中包含的成员已经设置好了默认值。

如果是基本数据类型:

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

如果数组中存储元素类型为引用类型,默认值为 null

之后如果写了带参的构造方法,那么就会再一次赋值。

5. 设置对象头信息

6. 调用构造方法,给对象中各个成员赋值

5.4 就地初始化

在声明成员变量时,就直接给出了初始值。

public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}

注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值