Java SE(6)——类和对象

1.初始面向对象

1.1 什么是面向对象

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

1.2 面向过程&面向对象的区别

这里以洗衣服为例:
1.手洗衣服过程

按照以上方式洗衣服,我们必须要亲自完成每一个阶段,其中每个阶段的处理方式也要我们自己来把握,比如:加水量,洗衣粉的量,搓衣服的力度等等。如果某个以后不洗衣服,改成洗鞋子,那么以上的流程就不一样了。按照这种方式来写代码,将来对代码进行扩展维护 就比较困难
2.现在洗衣服的过程

现在洗衣服会经常用到洗衣机来完成,那么使用洗衣机来洗衣服一般涉及四个对象:人,衣服,洗衣机,洗衣粉

洗衣服的过程如下:

人把衣服放进洗衣机,加入洗衣粉,启动洗衣机

以上整个过程中,主要是人,衣服,洗衣机,洗衣粉这四个对象在交互。人不需要关注洗衣机是怎么洗衣服的,人只需要把衣服放进去,加洗衣粉,然后启动开关就行了。

换言之,人只需要面向洗衣机这个对象,就能完成洗衣服,而不需要面向洗衣服的各个过程,这就是面向对象和面向过程的区别

2.类的定义和使用

面向对象编程关注的是对象,对象就相当于是生活中的实物,比如:洗衣机。但是计算机不知道什么是洗衣机,这需要我们开发人员来告诉计算机什么是洗衣机

上图左边的信息就是对洗衣机的描述,我们可以用这种描述信息来表示一个具体的实物,这个过程称为抽象。所谓抽象,指的是从具体事物中抽取共同的、本质的特征,忽略次要的、非本质的特征。但是这些简化的抽象结果(图片左侧的描述信息)也不能被计算机识别,开发人员就需要使用某种面向对象的编程语言来进行描述,比如:Java

2.1 简单认识类

**类是对一个实体(对象)来进行描述的。**主要描述该实体(对象)有哪些属性,有哪些功能,描述完成后计算机就可以识别了。以上述洗衣机为例,我们使用左边的描述信息来抽象一台洗衣机,但是计算机并不能识别这些描述信息,我们可以将这些信息放进一个类里面,然后计算机就可以识别了

2.2 类的定义格式

定义类的具体语法如下:

java 复制代码
    field;      //属性或者成员变量
    method;     //行为或者成员方法 } ```

class是定义类使用的关键字,ClassName是类的名字,{}中是类的主体,类的主体中定义了类有哪些属性,有哪些方法

下面我们来定义一个类来描述一台洗衣机:

java 复制代码
public class WashingMachine {
    //品牌
    public String brand;
    //型号
    public String model;
    //大小
    public Double size;
    //重量
    public Double weight;
    //价格
    public Double price;
    //洗衣服
    public void wash() {
        System.out.println("Washing clothes...");
    }
    //脱水
    public void dehydrate() {
        System.out.println("Dehydrating clothes...");
    }
}

上述过程中,我们使用Java语言定义了一个洗衣机类,通过javac编译后转换为字节码文件,再由JVM翻译就可以被计算机识别了(Java文件如何被计算机识别,请看博文Java虚拟机------JVM(Java Virtual Machine)解析一
注意1:

  • 类名采用大驼峰形式。大驼峰:每个单词的首字母大写
  • 类的成员变量/方法暂时使用public修饰。public是访问限定修饰符之一,后面讲到继承时再介绍
  • 类的成员变量/方法暂时不使用static修饰

下面再来定义两个类来熟悉一下类的定义

(1)定义Dog类

java 复制代码
class Dog{
    public String name;
    public int age;
    public String color;
    //
    public void eat(){
        System.out.println("eat food");
    }
    public void bark(){
        System.out.println("汪汪汪...");
    }
}

(2)定义学生类

java 复制代码
class Student{
    public String name;
    public int age;
    public int id;
    public double score;
    public String height;
    public String weight;
    //
    public void exam(){
        System.out.println("参加考试");
    }
    public void doHomework(){
        System.out.println("写作业");
    }
}

注意2:

  • 一个Java文件建议定义一个类
  • 使用public修饰的类在一个Java文件中只能存在一个
  • 使用public修饰的类的类名 和所在文件的文件名相同

3.类的实例化

3.1 什么是实例化?

在上述代码中,我们定义了WashingMachine、Dog和Student类,就相当于在计算机中定义了这三个新的数据类型。和int、float等基本数据类型一样,只不过int和float是Java内置的2类型,而WashingMachine这些是用户自定义的类型,我们通过这些自定义类型就可以定义实例/对象 。而通过 来定义实例/对象的过程,称之为实例化 ,在Java中需要借助new 关键字来完成实例化

3.2 如何访问对象中的成员变量/方法?

java 复制代码
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "Dog";
        System.out.println(dog.name);
        dog.age = 18;
        System.out.println(dog.age);
        dog.color = "blue";
        System.out.println(dog.color);
        dog.eat();
        dog.bark();
    } } ```

运行结果如下:

注意:

  • Java中使用.来访问对象中的成员变量/方法
  • 同一个类可以实例化多个对象

3.3 类和对象的关系

是一种抽象的数据类型 ,它可以实例化一组具有相同属性(成员变量)和行为(成员方法)的对象。类可以看作是一个蓝图或者模板,用于创建对象
对象是类的具体实现,每个对象都可以给自己的属性(成员变量)赋予独特的
房屋和具体的房子

  • 类(Class):房屋(House)
    属性(Attributes):房间数量、面积、楼层数、地址
    方法(Methods):建造、入住、出售
  • 对象(Object):具体的房子,如"张三的家"
    实例化(Instantiation):张三的家是一个具体的房子,它有5个房间,面积是150平方米,3层楼,地址是"北京市朝阳区XX路"
    行为(Behavior):张三的家可以被建造、入住或出售

4.this关键字

4.1 为什么要使用this?

这里举个例子

预期结果:2025-5-1

实际结果:null-null-null

原因分析:

java 复制代码
    public void setDate(String year, String month, String day) {
        year = year;
        month = month;
        day = day;
    }

这个方法中,形参的参数名和MyDate类的成员变量吗名一致,当给year赋值时,编译器无法区分year是成员变量还是方法的局部变量,在这种情况下会优先调用局部变量,相当于是自己给赋值

java 复制代码
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }

这个方法中没有形参,调用的参数(year/month/day)只能是MyDate类的成员变量,由于setDate方法没有给成员变量赋值,所以printDate打印的时候才会打印出null-null-null。分析到这里就明白了,问题在于当方法的形参名和类的成员变量名一致时,该如何进行区分呢?这就要借助this关键字

4.2 this是什么?

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

通过代码来解释一下:

当编译器去调用成员变量的时候都会通过this关键字来调用。this引用指向当前对象,这句话又该怎么理解呢?以上面的代码为例

这里的当前引用指的就是myDate。换言之,this = myDate。

java 复制代码
    public void setDate(String year1, String month1, String day1) {
        //this.year的含义是:myDate指向的对象中的year
        //this.year = year1;这段代码的意思是:把   方法形参year1   赋值给   myDate指向的对象中的year
        this.year = year1;
        this.month = month1;
        this.day = day1;
    }

修改之后的代码如下:

java 复制代码
public class MyDate {
    public String year;
    public String month;
    public String day;
    //
    public void setDate(String year1, String month1, String day1) {
        //使用this关键字来区分哪个是成员变量,哪个是方法形参
        this.year = year1;
        this.month = month1;
        this.day = day1;
    }
    //
    public void printDate(){
        System.out.println(this.year + "-" + this.month + "-" + this.day);
    }
    //
    public static void main(String[] args) {
        MyDate myDate = new MyDate();
        myDate.setDate("2025","5","1");
        myDate.printDate();
    }
}

注意:在刚学习Java的使用就提醒过,使用一个变量之前需要给该变量赋初值,否则会报错

但是:

打印结果是null-null-null,并没有报错。这是怎么回事呢?

原因是,对于成员变量 来说,如果没有进行初始化,会有⼀个对应的默认值
String类型是引用类型,会赋予默认值null,所以不会报错

默认值遵循如下规则:

数据类型 默认值
byte 0
short 0
int 0
long 0
boolean FALSE
float 0.0f
double 0
引用类型(reference) null

5.对象的构造及初始化

上文已经介绍到,成员变量在没有赋初值的时候会赋予默认值,这就是对象的默认初始化。说实话,我个人认为这是防止程序报错而出现的一个措施,不算正常的初始化操作,那么对象的初始化有哪些方式呢?

5.1 就地初始化

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

java 复制代码
public class MyDate {
    public String year = "2025";
    public String month = "5";
    public String day = "1";
    //
    public void setDate(String year1, String month1, String day1) {
        this.year = year1;
        this.month = month1;
        this.day = day1;
    }
    //
    public void printDate(){
        System.out.println(this.year + "-" + this.month + "-" + this.day);
    }
    //
    public static void main(String[] args) {
        MyDate myDate = new MyDate();
        myDate.printDate();
    }
}

5.2 自定义方法初始化

用户自定义一个方法来进行成员变量的初始化操作

java 复制代码
public class MyDate {
    public String year;
    public String month;
    public String day;
    //
    public void setDate(String year1, String month1, String day1) {
        this.year = year1;
        this.month = month1;
        this.day = day1;
    }
    //
    public void printDate(){
        System.out.println(this.year + "-" + this.month + "-" + this.day);
    }
    //
    public static void main(String[] args) {
        MyDate myDate = new MyDate();
        myDate.setDate("2025","5","1");
        myDate.printDate();
    }
}

5.3 构造方法初始化

上面介绍的两种初始化方法,说实话都不是很常见。就地初始化灵活性太差;自定义方法初始化还需要创建并调用自定义的方法,不太方便

那么,有没有既灵活又方便的初始化方式呢?

那就是使用构造方法来初始化

5.3.1 什么是构造方法?

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

java 复制代码
public class MyDate {
    public String year;
    public String month;
    public String day;
    //
    public MyDate(String year, String month, String 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) {
        MyDate myDate = new MyDate("2025","5","1");
        myDate.printDate();
    }
}

在使用new关键字 实例化对象的时候,编译器会根据括号内的参数数量和类型 来判断调用哪个构造方法。这段代码中,new对象的时候一共传递了三个String类型的参数,编译器就会查找哪个构造方法的参数列表能与之对应

5.3.2 构造方法注意事项&使用规范

注意:

  • 1.构造方法名必须和类名一致
  • 2.没有返回值,设置void也不行
  • 3.创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  • 4.构造方法可以重载(用户根据自己的需求创建不同参数列表的构造方法)
  • 一般来说,构造方法使用public修饰

注意6:

当用户没有手动添加构造方法的时候,编译器会默认生成一份无参的 构造方法。当用户显式 地添加构造方法(不论有参还是无参)的时候,编译器将不再默认生成构造方法

左图中 ,用户没有显式地添加构造方法,编译器会默认生成 一个无参的构造方法,当用户需要实例化一个不赋初值地对象时,就能匹配到该无参构造方法;右图中 ,用户显式地添加一个构造方法,参数列表有三个形参,当用户需要实例化一个不赋初值地对象时,由于编译器没有 默认生成一个无参的构造方法,导致匹配失败 。所以,构造方法也有一个不成文的使用规范:当用户显式地添加构造方法后,不论无参的构造方法有没有用,都建议添加上

5.3.2 构造方法中使用this来简化代码

java 复制代码
public class MyDate {
    public String year;
    public String month;
    public String day;
    //
    public MyDate() {
        this("2025","5","1");
    }
    public MyDate(String year, String month, String day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //
    public void printDate(){
        System.out.println(this.year + "-" + this.month + "-" + this.day);
    }
}
class Test{
    public static void main(String[] args) {
        MyDate myDate = new MyDate();
        myDate.printDate();
    }
}

在上述代码中,new对象的时候会默认调用无参的构造方法,无参的构造方法内使用了this()代码,编译器就会根据括号内的参数数量和类型 去查找参数列表与之匹配的构造方法
注意:

  • this()必须是构造方法中的第一条语句
  • this()不能形成环的调用
相关推荐
Jiaberrr25 分钟前
uniapp 实现低功耗蓝牙连接并读写数据实战指南
java·前端·javascript·vue.js·struts·uni-app
家乡的落日27 分钟前
一、I/O的相关概念
java
码熔burning28 分钟前
【MQ篇】RabbitMQ之死信交换机!
java·分布式·rabbitmq·mq
黄雪超2 小时前
JVM——Java的基本类型的实现
java·开发语言·jvm
工业互联网专业2 小时前
基于web的可追溯果蔬生产过程的管理系统
java·vue.js·spring boot·毕业设计·源码·课程设计·可追溯果蔬生产过程的管理系统
程序猿大波2 小时前
基于Java,SpringBoot,HTML水文水质监测预警系统设计
java·开发语言·spring boot
海鸥813 小时前
在K8S迁移节点kubelet数据存储目录
java·kubernetes·kubelet
jackson凌3 小时前
【Java学习笔记】递归
java·笔记·学习
鑫—萍3 小时前
C++——入门基础(2)
java·开发语言·jvm·数据结构·c++·算法