Java--类和对象(上)

本篇博客探讨内容
1. 类的定义方式以及对象的实例化
2. 类中的成员变量和成员方法的使用
3. 对象的整个构造及初始化过程

 前言

本文是根据课堂课件和我个人初学理解整理的笔记,旨在帮助自己梳理知识点。初学阶段,理解可能有误,欢迎指正探讨


1. 面向对象初步认识


1.1 什么是面向对象

Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。

面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。

1.2 面向对象与面向过程

面向过程(Procedure-Oriented)​

🔍 ​核心思维​:"如何一步步完成任务?"

  • 把程序看作操作流程的集合
  • 像写菜谱般描述具体步骤
  • 关注点:​算法步骤 + 数据传递

📌 ​本质​:程序员是"操作员",亲自控制每个细节


面向对象(Object-Oriented)​

🔍 ​核心思维​:"谁负责什么任务?"

  • 把程序看作交互对象的集合
  • 像组建团队般分配职责
  • 关注点:​对象职责 + 协作关系

📌 ​本质​:程序员是"管理者",指挥对象各司其职

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

2. 类的定义与使用


2.1 简单认识类

📦 ​官方定义​:类是创建对象的模板,定义了对象的属性(状态)​行为(方法)​

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

2.2 类的定义格式

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

    //创建类
    class ClassName{
        field;  //字段(属性)或者 成员变量
        method; //行为 或者 成员方法
    }
class定义类的关键字,ClassName为类的名字,类主体 {}​
  • 边界符号:包裹所有成员变量和方法
  • 位置要求:紧随类名后
    • ✅ class Dog{...}
    • ❌ class Dog ...{ }(编译错误)
    • 必须是有效标识符(非数字开头、无空格)
类中包含的内容称为类的成员。
属性主要用来描述类的,称之为类的成员属性或者类成员变量。
方法主要说明类具有哪些功能,称为类的成员方法。

注意事项
类名注意采用大驼峰定义 
  • 首字母大写)
    • ✅ Student BankAccount
    • ❌ student bank_account
  • 必须是有效标识符(非数字开头、无空格)
成员前写法统一为public,后面会详细解释
此处写的方法不带 static 关键字. 后面会详细解释

2.2.1定义类

class PetDog {
    public String name;//名字
    public String color;//颜色
    // 狗的属性
    public void barks() {
        System.out.println(name + ": 旺旺旺~~~");
    }
    // 狗的行为
    public void wag() {
        System.out.println(name + ": 摇尾巴~~~");
    }
}
📌注意事项:
1. 一般一个文件当中只定义一个类,在Java中一个源文件(*.java)只可以存在一个主类
2. main方法所在的类一般要使用public修饰
3. public修饰的类必须要和文件名相同
4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改(给同学演示)

3. 类的实例化


 3.1 什么是实例化

        定义了一个类,就相当于在计算机中定义了一种新的类型,与intdouble类似,只不过intdoublejava语言自 带的内置类型,而类是用户自定义了一个新的类型。
        比如上述的:PetDog类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)
用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象

 

    public static void main(String[] args) {
        PetDog dogh = new PetDog(); //通过new实例化对象
        dogh.name = "阿黄";
        dogh.color = "黑黄";
        dogh.barks();
        dogh.wag();
        
        PetDog dogs = new PetDog();
        dogs.name = "阿黄";
        dogs.color = "黑黄";
        dogs.barks();
        dogs.wag();
    }

输出结果:

阿黄: 旺旺旺~~~
阿黄: 摇尾巴~~~
阿黄: 旺旺旺~~~
阿黄: 摇尾巴~~~

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

3.2 类和对象的说明

  1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
  2. 类是一种自定义的类型,可以用来定义变量。
  3.  一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量。
  4.  做个比方--类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。

 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 static void main(String[] args) {
        //构造日期类型对象d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();

        //对d1进行日期设置
        d1.setDay(2025,6,17);
        d2.setDay(2025,6,18);
        d3.setDay(2025,6,19);

        //打印其中日期的内容
        d1.printDay();
        d2.printDay();
        d3.printDay();
    }
}

以上代码定义了一个日期类,并在main方法中创建了三个d1,d2,d3对象,通过Date类中的成员方法setDateprintDate分别进行设置和打印。 

那这时有个两个疑问🤔:

  1. 若形参名和成员变量名相同
        public void setDate(int year,int month, int day){ //成员方法
            year = year;
            month = month;
            day = day;
        }

    那么此时函数体是给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?...❓

  2. 当三个对象都在调用setDateprintDate函数,但是这两个函数中没有任何有关对象的说明setDateprintDate函数如何知道打印的是那个对象的数据呢

4.2 什么是this引用

        👀this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问

只是所有的操作对于用户来说都是不可见的,即不需要用户来传递,编译器自动完成✅

由此可以将代码修改为如⬇️:

    public void setDate(int year,int month, int day){ //成员方法
        this.year = year;
        this.month = month;
        this.day = day;
    }
📌注意:this引用的是调用成员方法的对象(d1,d2,d3)
根据控制台输出setDay方法的引用地址可以看出,此时正在为d1对象进行实例化
此时⬆️图为d2,以此类推至d3...

4.3 this引用的特性

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

⬆️图右侧代码是可以通过编译的 

4.4 关于this语句的小提醒


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

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

此处两个方法没有区别,都可以通过编译 

✨ ​但建议

  1. 坚持使用this提升代码清晰度(尤其多开发者协作时)
  2. 将格式逻辑与打印功能分离(符合单一职责原则)
  3. 通过封装降低维护成本(如需调整日期格式只需改一处)
  4. 垂直缩进保持视觉一致性

严格执行此规范可避免大型项目中80%的成员变量访问歧义问题。

5. 对象的构造及初始化


5.1 构造方法

在Java方法内部声明局部变量时,​必须赋予初始值才能通过编译器的检查,因为编译器无法容忍未初始化的局部变量存在潜在风险。

对于局部变量只需赋予初识即可,但对于:对象⬇️

public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(2021,6,9);
    d.printDate();
}

 需要调用SetDay方法来进行设置。那么,

1. 每次对象创建好后调用SetDay方法设置具体日期,比较麻烦,那对象该如何初始化?
2. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

 5.1.1 概念 

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

    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
        d.printDay(); // 2021-6-9
    }
//其余内容不变,还是上文的Dtae类

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

5.1.2 特征

1. 名字必须与类名相同
2. 没有返回值类型,设置为void也不行
3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
    // 无参构造方法
    public Date(){
        this.year = 2025;
        this.month = 6;
        this.day = 17;
    }
    //带三个参数的构造方法
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)方法被调用了");
    }

⬆️两个构造方法:名字相同,参数列表不同,构成了方法重载 

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

注意:一但用户定义,则编译器不再生成

6.构造方法中,可以通过this调用其他构造方法来简化代码 ⬇️

    // 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
    // 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
    public Date(){
        //System.out.println("this语句必须是构造方法中的第一句");取消注释会报错!
        this(2025,6,17);
    }
    //带有三个参数的构造方法
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

⚠️this语句不能形成环!

7. this语句绝大多数情况下使用public来修饰,特殊场景下会被private修饰(之后再做详细介绍)

5.2 默认初识化

上文提到,在定义局部变量时必须要初识化,那么为什么类的成员变量却不用呢? 

class Date{
    public int year;
    public int month;
    public int day;
    
    
    public Date(int year, int month, int day){
        //成员变量在定义时并没有初始值,为什么就可以使用呢??🤔
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public static void main(String[] args) {
        Date d = new Date(2025,6,17);
    }
}

对于new关键字的背后我们需要知道:

        Date d = new Date(2025,6,17);
在程序层面只是简单的一条语句,在JVM层面需要做好多事情:
        1. 检测对象对应的类是否加载了,如果没有加载则加载
        2. 为对象分配内存空间
        3. 处理并发安全问题
        比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
        4. 初始化所分配的空间
        即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值
数据类型默认值
byte0
char'lu0000'
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull
        5. 设置对象头信息(关于对象内存模型)
        6. 调用构造方法,给对象中各个成员赋值

 

过程简单示例图⬆️

5.3就地初始化

就地初始化是指在声明成员变量时直接赋初始值的初始化方式。

这种方式为成员变量提供默认值,无需在构造函数中重复设置。

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) {
        // 编译器会在此处插入初始化语句 year=1900, month=1, day=1
        // 然后再执行构造函数内的具体赋值操作
        this.year = year;
        this.month = month;
        this.day = day;
    }
    
    public static void main(String[] args) {
        Date d1 = new Date(2021, 6, 9); // 使用带参构造
        Date d2 = new Date();           // 使用无参构造
    }
}

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

5.4 关于构造的小技巧

在编写类时,如果我们需要创建构造方法,特别是需要初始化多个字段时,手动编写构造方法会比较繁琐。

现代IDE(集成开发环境)提供了快捷生成构造方法的功能。

如图所示,在编辑器中,选中类名或字段区域,通过右键菜单或快捷操作(如Alt+Insert),选择“生成...”(Generate)选项,然后选择“构造函数”(Constructor),接着在弹出的窗口中勾选需要初始化的字段(例如:year, month, day),IDE便会自动生成包含这些字段初始化的构造方法

 生成结果⬇️

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值