JavaSE 类和对象

Java SE 类与对象

1. 面向对象的初步认识

1.1 什么是面向对象

面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。对于Java来说,一切皆对象

1.2 面向对象与面向过程

就拿洗衣服这件事来说,传统的洗衣方式更注重的是洗衣服的过程

JavaSE 类和对象_第1张图片

在注重过程的情况下,若衣服需要清洗的程度不同,时间长度,拧干方式不同,处理起来就比较麻烦

若按照这种方式来写代码,将来扩展或者维护起来会比较麻烦

而现代的洗衣方式更注重的是对象之间的交互

JavaSE 类和对象_第2张图片

面向对象的方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么洗衣服,如何来甩干衣服的,用户不用去关心,只需要将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成。

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

2. 类的定义和使用

面向对象程序设计关注的是对象,而对象就是现实生活中的实体,

2.1 简单认识类

类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来做什么),描述完成后计算机就可以对这个对象进行识别了

比如:洗衣机 在Java中可以将其看成是一个类别
属性:产品品牌,型号,产品重量,外观尺寸,颜色...
功能:洗衣,烘干,定时,脱水...

2.2 类的定义格式

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

//创建类
class ClassName {
	field; //字段(属性) 或 成员变量
	method; //行为 或成员方法
}

class为定义类的关键字,ClassName为类的名字,{}中为类的主体。

类中包含的内容称为类的成员。其中,属性主要是用来描述类的,称之为类的成员属性成员变量方法主要说明类有哪些功能,称为类的成员方法

代码示例:

public class WashMachine {
    public String brand; //品牌
    public String type; //型号
    public double weight; //重量
    public double length;//长度
    public double width; //宽度
    public double height; //高度
    public String color; //颜色

    public void washClothes() { //洗衣
        System.out.println("洗衣功能");
    }

    public void dryClothes() { //脱水
        System.out.println("脱水功能");
    }

}

采用Java语言将洗衣机类在计算机中定义完成,结果javac编译之后形成.class文件,在JVM的基础上计算机就可以识别了。

注:

  • 类名采用大驼峰定义

  • 一般一个文件当中只定义一个类

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

  • public修饰的类必须要和文件名相同

3. 类的实例化

3.1 什么是实例化

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

用类类型创建对象的过程,称为类的实例化

在java中采用new关键字配合类名来实例化对象。

类名 引用变量名 = new 类名();

JavaSE 类和对象_第3张图片

代码示例:

class PetDog {
    //狗的属性
    public String name;
    public String color;

    //狗的行为
    public void barks() {
        System.out.println(this.name + "旺旺叫");
    }

    public void wag() {
        System.out.println(this.name + "摇尾巴");
    }
}


public class Main {
    public static void main(String[] args) {

        PetDog petDog1 = new PetDog();
        PetDog petDog2 = new PetDog();

        petDog1.name = "阿黄";
        petDog1.color = "黄色";
        petDog1.barks();
        petDog1.wag();

        System.out.println("============");

        petDog2.name = "赛虎";
        petDog2.color = "棕色";
        petDog2.barks();
        petDog2.wag();

    }
}

//执行结果
阿黄旺旺叫
阿黄摇尾巴
============
赛虎旺旺叫
赛虎摇尾巴

JavaSE 类和对象_第4张图片

注:

  • new关键字用于创建一个对象的实例
  • 使用.来访问对象中的属性和方法
  • 同一个类可以创建多个对象

3.2 类和对象说明

  1. 只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
  2. 类是一种自定义的类型,可以用来定义变量
  3. 一个类可以实例化出多个对象,但只有被实例化出的对象才能占用实际的物理空间,存储类成员变量

4. this引用

4.1 为什么要有this引用

先看这段代码:

public class Date {

    public int year;
    public int month;
    public int day;

    public void setDay(int year,int month,int day) {
        year = year;
        month = month;
        day = day;
    }

    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }

    public static void main(String[] args) {

        //构建三个日期类型的对象
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();

        //对三个对象进行日期设置
        d1.setDay(2023,8,1);
        d2.setDay(2024,7,15);
        d3.setDay(2025,7,25);

        //打印日期对象中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();


    }

}

//执行结果
0/0/0
0/0/0
0/0/0

JavaSE 类和对象_第5张图片

以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date类中的成员方法对对象进行设置和打印,代码整体逻辑非常简单,看着没有任何问题,可结果为什么会出问题呢?

一切和下面这段代码脱不了关系:

public void setDay(int year,int month,int day) {
	year = year;
	month = month;
	day = day;
}

在这段代码里,函数体中到底是谁在给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?看似已经出现了分歧,并且setDate和printDate函数又是如何知道打印的是哪个对象的数据呢?

JavaSE 类和对象_第6张图片

如何解决这些问题,这时就轮到我们this引用出场了!

4.2 什么是this引用

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

代码示例:

public class Date {

    public int year;
    public int month;
    public int day;

    public void setDay(int year,int month,int day) {
        this.year = year; //这里使用了this引用
        this.month = month;
        this.day = day;
    }

    public void printDate() {
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }

    public static void main(String[] args) {

        //构建三个日期类型的对象
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();

        //对三个对象进行日期设置
        d1.setDay(2023,8,1);
        d2.setDay(2024,7,15);
        d3.setDay(2025,7,25);

        //打印日期对象中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();


    }

}

//执行结果
2023/8/1
2024/7/15
2025/7/25

JavaSE 类和对象_第7张图片

注:this引用的是调用成员方法的对象

public static void main(String[] args) {
	Date d = new Date();
	d.setDay(2020,9,15);
	d.printDate();
}

JavaSE 类和对象_第8张图片

4.3 this引用的特性

  1. this的类型:对于类类型引用,即哪个对象调用就是哪个对象的引用类型
  2. this只能在"成员方法"中使用
  3. 在"成员方法"中,this只能引用当前对象,不能在引用其他对象
  4. this是"成员方法"第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会赋值将调用成员方法对象的引用传递给该成员方法,this负责来接收

JavaSE 类和对象_第9张图片

5. 对象的构造及初始化

5.1 构造方法

5.1.1 概念

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

代码示例:

public class Date1 {

    public int year;
    public int month;
    public int day;

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

    public void printDate() {
        System.out.println("Date(int,int,int)方法被调用了");
    }

    public static void main(String[] args) {


        Date1 d = new Date1(2023,8,13); //此处创建了一个Date1类型的对象,并没有显示调用构造方法
        d.printDate();
    }

}

//执行结果
Date(int,int,int)方法被调用了

JavaSE 类和对象_第10张图片

注:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间

5.2.2 特性
  1. 构造方法名必须与类名相同
  2. 没有返回值类型,设置void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)

代码示例:

public class Date2 {

    public int year;
    public int month;
    public int day;

    public Date2() {
        this.year = 2020;
        this.month = 7;
        this.day = 25;
    }

    public Date2(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);
    }

    public static void main(String[] args) {


        Date2 d = new Date2();
        d.printDate();
    }

}
//执行结果
2020/7/25

注:因为上述两个构造方法名字相同,参数列表不同,因此构成了方法重载

  1. 如果用户没有显示定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的
public class Date2 {

    public int year;
    public int month;
    public int day;

    public void printDate() {
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }

    public static void main(String[] args) {

        Date2 d = new Date2();
        d.printDate();
    }

}

//执行结果
0/0/0

注:一旦用户定义,编译器则不会自动生成构造方法

  1. 构造方法中,可以通过this调用其他构造方法来简化代码
public class Date3 {
	
    public int year;
    public int month;
    public int day;
	
    //无参构造方法-内部给各个成员赋初始值,该部分功能与三个参数的构造方法重复
    //可以在无参构造方法中通过this调用带有三个参数的构造方法,但this(1900,1,1)必须是构造方法中第一条语句
    public Date3() {
        this(1900,1,1);
    }
	
    
    //带有三个参数的构造方法
    public Date3(int year,int month,int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

}

注:

  • this()必须是构造方法中第一条语句

  • 不能形成环

    public Date3() {
            this(1900,1,1);
        }
    	
    
    public Date3(int year,int month,int day) {
    		this();
        }
    
    //会报错
    
  1. 绝大多数情况下使用public来修饰,特殊场景下会用private修饰

5.2 成员变量初始化特点

在Java方法内部定义一个局部变量是,必须要初始化,否则会编译失败,但成员变量可以不用初始化也能使用

原因:在对象空间被申请好后,对象中包含的成员已经设置好了初始值

数据类型 默认值
byte 0
char ‘\u0000’
short 0
int 0
long 0L
boolean false
float 0.0f
double 0.0
reference null

5.3 就地初始化

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

代码示例:

public class Date4 {
    public int year = 1922;
    public int month = 7;
    public int day = 25;

    public Date4() {

    }

    public Date4(int year,int month,int day) {
        
    }
    public void printDate() {
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
    public static void main(String[] args) {
        Date4 d1 = new Date4(2022,6,7);//在这里传入的参数没有被使用到
        Date4 d2 = new Date4();
        d1.printDate();
        d2.printDate();
    }
}

//执行结果
1922/7/25
1922/7/25

JavaSE 类和对象_第11张图片

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

你可能感兴趣的:(JavaSE,java)