Java入门(类和对象)

目录

一、面向对象初步认知

[1.1 什么是面向对象](#1.1 什么是面向对象)

[1.2 面向对象与面向过程的对比](#1.2 面向对象与面向过程的对比)

二、类的定义与对象的实例化

[2.1 类的定义格式](#2.1 类的定义格式)

[2.2 对象的实例化](#2.2 对象的实例化)

(1)实例化格式

(2)访问对象成员

(3)代码示例

(4)类和对象的核心理解

[三、this 关键字:解决对象的标识问题](#三、this 关键字:解决对象的标识问题)

[3.1 this 的本质](#3.1 this 的本质)

[3.2 this 的核心使用场景](#3.2 this 的核心使用场景)

(1)区分同名的形参和成员变量

(2)调用当前对象的成员方法

(3)在构造方法中调用其他构造方法

[3.3 this 的特性](#3.3 this 的特性)

四、对象的构造与初始化

[4.1 默认初始化](#4.1 默认初始化)

[4.2 就地初始化](#4.2 就地初始化)

[4.3 构造方法初始化](#4.3 构造方法初始化)

(1)构造方法的语法规则

(2)构造方法的分类与使用

[4.4 对象初始化的执行顺序](#4.4 对象初始化的执行顺序)

[五、对象的打印:重写 toString 方法](#五、对象的打印:重写 toString 方法)

[5.1 重写 toString 方法示例](#5.1 重写 toString 方法示例)

[六、包:Java 的类组织方式](#六、包:Java 的类组织方式)

[6.1 包的基本使用](#6.1 包的基本使用)

(1)导入包中的类

(2)自定义包

[6.2 常见的内置包](#6.2 常见的内置包)

[6.3 包的访问权限](#6.3 包的访问权限)

七、封装:面向对象的核心特性之一

[7.1 封装的实现方式](#7.1 封装的实现方式)

[7.2 封装代码示例](#7.2 封装代码示例)

[7.3 封装的好处](#7.3 封装的好处)

[7.4 Java 的四种访问限定符](#7.4 Java 的四种访问限定符)

[八、static 关键字:类的共享成员](#八、static 关键字:类的共享成员)

[8.1 static 修饰成员变量(静态成员变量)](#8.1 static 修饰成员变量(静态成员变量))

(1)特性

(2)代码示例

[8.2 static 修饰成员方法(静态成员方法)](#8.2 static 修饰成员方法(静态成员方法))

(1)特性

(2)代码示例

[8.3 静态成员的初始化](#8.3 静态成员的初始化)

九、代码块:对象与类的初始化补充

[9.1 普通代码块](#9.1 普通代码块)

[9.2 实例代码块(构造块)](#9.2 实例代码块(构造块))

[9.3 静态代码块](#9.3 静态代码块)

(1)核心特性

(2)代码示例

十、总结


在 Java 的学习道路上,类和对象是面向对象编程(OOP)的基石,Java 作为一门纯面向对象的语言,一切皆为对象。掌握类和对象的相关知识,能让我们更贴合人类的认知习惯设计程序,让大型程序的开发、扩展和维护变得更加友好。本文将从面向对象的基础认知出发,逐步讲解类的定义、对象实例化、this 关键字、构造方法,再到包、封装、static 关键字和代码块等进阶内容,结合代码示例全方位解析,让你轻松吃透类和对象的核心考点。

一、面向对象初步认知

1.1 什么是面向对象

面向对象是一种解决问题的编程思想,核心是依靠对象之间的交互完成业务逻辑。在面向对象的世界里,每个实体都被抽象为对象,对象拥有自身的属性和行为,程序的执行过程就是对象之间传递消息、调用方法的过程。

1.2 面向对象与面向过程的对比

为了更直观理解,我们以洗衣服为例对比两种思想的差异:

  • 面向过程:注重执行步骤,需要依次完成「放水→放衣服→放洗衣粉→手搓→换水→拧干→晾衣服」,步骤缺一不可,若要洗鞋子又要重新设计一套步骤,代码扩展性差。
  • 面向对象:不关注具体执行过程,只关注参与的对象(衣服、洗衣机、洗衣粉),通过对象交互完成功能(将衣服放入洗衣机,加入洗衣粉,启动洗衣机即可),洗衣机的内部实现对用户透明,代码复用性和扩展性更强。

注意:二者并非对立关系,也无好坏之分,各有适用场景。简单的业务逻辑(如计算两数之和)用面向过程更高效,复杂的大型项目(如电商系统)用面向对象更易维护。

二、类的定义与对象的实例化

对象是现实世界的实体,而类是对对象的抽象描述 ,规定了对象的属性(成员变量)和行为(成员方法)。简单来说:类是对象的模板,对象是类的具体实例

2.1 类的定义格式

在 Java 中使用class关键字定义类,遵循大驼峰命名法,类的主体包含成员变量和成员方法,语法如下:

java 复制代码
// 类的定义
class 类名 {
    // 成员变量(属性):描述对象的特征
    修饰符 数据类型 变量名;
    // 成员方法(行为):描述对象的功能,无static关键字
    修饰符 返回值类型 方法名(参数列表) {
        方法体;
    }
}

示例:定义洗衣机类 WashMachine

java 复制代码
class WashMachine {
    // 成员变量:品牌、型号、重量、长宽高
    public String brand;
    public String type;
    public double weight;
    public double length;
    public double width;
    public double height;

    // 成员方法:洗衣、脱水、定时
    public void washClothes() {
        System.out.println(brand + "洗衣机正在洗衣");
    }

    public void dryClothes() {
        System.out.println(brand + "洗衣机正在脱水");
    }

    public void setTime(int minute) {
        System.out.println("设置洗衣时间为" + minute + "分钟");
    }
}

定义注意事项

  1. 一个文件一般只定义一个类;
  2. public修饰的类,类名必须与文件名完全一致;
  3. 成员变量前统一使用public(后续封装会优化修饰符),成员方法暂不加static

2.2 对象的实例化

定义类后,仅相当于创建了一种新的自定义类型,需要通过new关键字实例化才能创建具体的对象,占用实际的物理内存。

(1)实例化格式
java 复制代码
类名 对象名 = new 类名();
(2)访问对象成员

通过 **.** 操作符访问对象的成员变量和成员方法,语法:对象名.成员变量 / 对象名.成员方法(参数)

(3)代码示例
java 复制代码
public class TestWashMachine {
    public static void main(String[] args) {
        // 实例化两个洗衣机对象
        WashMachine machine1 = new WashMachine();
        WashMachine machine2 = new WashMachine();

        // 给machine1赋值成员变量
        machine1.brand = "樱花";
        machine1.type = "XPB150-150S";
        // 调用machine1的方法
        machine1.washClothes();
        machine1.setTime(30);

        // 给machine2赋值成员变量
        machine2.brand = "海尔";
        machine2.type = "EG100PRO";
        // 调用machine2的方法
        machine2.washClothes();
        machine2.dryClothes();
    }
}

输出结果

复制代码
樱花洗衣机正在洗衣
设置洗衣时间为30分钟
海尔洗衣机正在洗衣
海尔洗衣机正在脱水
(4)类和对象的核心理解
  1. 类是 "设计图",仅描述结构,不占用内存;对象是 "根据设计图建造的房子",占用实际内存;
  2. 一个类可以实例化多个对象,每个对象的成员变量独立存储,互不影响;
  3. new关键字是创建对象的核心,负责为对象分配内存空间。

三、this 关键字:解决对象的标识问题

在成员方法中,经常会遇到形参名与成员变量名相同 ,或者方法需要明确知道当前操作的是哪个对象 的问题,this关键字就是为了解决这些问题而生。

3.1 this 的本质

this成员方法的第一个隐藏参数 ,编译器会自动将调用方法的对象引用传递给this,因此this始终指向调用当前成员方法的对象

3.2 this 的核心使用场景

(1)区分同名的形参和成员变量
java 复制代码
class Date {
    public int year;
    public int month;
    public int day;

    // 形参名与成员变量名相同,用this区分
    public void setDay(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    // 用this访问当前对象的成员变量
    public void printDate() {
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
}
(2)调用当前对象的成员方法
java 复制代码
class Student {
    public String name;
    public void study() {
        System.out.println(name + "正在学习");
    }
    public void showAction() {
        // 用this调用当前对象的study方法,可省略this,编译器会自动补全
        this.study();
    }
}
(3)在构造方法中调用其他构造方法

通过this(参数)调用本类的其他构造方法,必须是构造方法的第一条语句,且不能形成循环调用。

java 复制代码
class Date {
    public int year;
    public int month;
    public int day;

    // 无参构造
    public Date() {
        // 调用有参构造,必须放在第一行
        this(1900, 1, 1);
    }

    // 有参构造
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

3.3 this 的特性

  1. this的类型与当前类的类型一致,指向具体的调用对象;
  2. this只能在非静态的成员方法 和构造方法中使用,静态方法中无this(静态方法属于类,不属于对象);
  3. this不能引用其他对象,只能指向当前对象;
  4. this由编译器自动传递,无需程序员手动传参。

四、对象的构造与初始化

局部变量必须初始化才能使用,而对象的成员变量即使不手动初始化,也能正常使用,这是因为 Java 为对象提供了默认初始化、就地初始化、构造方法初始化三种方式,保证成员变量有初始值。

4.1 默认初始化

当通过new创建对象时,JVM 会为对象的成员变量分配内存,并赋予默认值,默认值规则如下:

数据类型 默认值
整型(byte/short/int/long) 0/0L
浮点型(float/double) 0.0f/0.0
布尔型(boolean) false
字符型(char) '\u0000'
引用类型(String / 数组 / 类) null

示例

java 复制代码
class Date {
    public int year;
    public String month;
    public boolean isLeap;

    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d.year);    // 输出0
        System.out.println(d.month);  // 输出null
        System.out.println(d.isLeap); // 输出false
    }
}

4.2 就地初始化

在声明成员变量时,直接为其赋值,这是最直观的初始化方式。

java 复制代码
class Date {
    // 就地初始化
    public int year = 2024;
    public int month = 10;
    public int day = 1;
}

4.3 构造方法初始化

构造方法是特殊的成员方法 ,专门用于对象的初始化,在创建对象时由编译器自动调用,且对象生命周期内仅调用一次

(1)构造方法的语法规则
  1. 方法名必须与类名完全一致,包括大小写;
  2. 没有返回值类型,甚至不能写void
  3. 修饰符一般为public(特殊场景用private,如单例模式);
  4. 可以重载(参数列表不同)。
(2)构造方法的分类与使用
  • 无参构造 :无参数,若用户未显式定义任何构造方法,编译器会自动生成默认的无参构造
  • 有参构造:带参数,用于为成员变量赋初始值,用户定义后,编译器不再生成默认无参构造。

示例

java 复制代码
class Student {
    public String name;
    public int age;
    public double score;

    // 无参构造:用户手动定义
    public Student() {
        System.out.println("无参构造被调用");
    }

    // 有参构造1:初始化姓名和年龄
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造1被调用");
    }

    // 有参构造2:初始化姓名、年龄、成绩(方法重载)
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
        System.out.println("有参构造2被调用");
    }

    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
    }
}

// 测试构造方法
public class TestStudent {
    public static void main(String[] args) {
        Student s1 = new Student(); // 调用无参构造
        Student s2 = new Student("张三", 18); // 调用有参构造1
        Student s3 = new Student("李四", 19, 95.5); // 调用有参构造2
        s3.showInfo(); // 输出:姓名:李四,年龄:19,成绩:95.5
    }
}

4.4 对象初始化的执行顺序

当同时存在就地初始化和构造方法时,就地初始化先执行,构造方法后执行,最终构造方法会覆盖就地初始化的值。

java 复制代码
class Person {
    public String name = "默认姓名"; // 就地初始化
    public int age = 0;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Person p = new Person("王五", 20);
        System.out.println(p.name); // 输出:王五(构造方法覆盖就地初始化)
    }
}

五、对象的打印:重写 toString 方法

直接打印对象的引用时,输出的是类的全限定名 @对象的哈希码值 (如com.test.Student@1b6d3586),这是因为Object类的toString方法默认实现如此。为了让打印结果更直观,需要重写 toString方法,自定义打印格式。

5.1 重写 toString 方法示例

java 复制代码
class Person {
    public String name;
    public int age;
    public String gender;

    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    // 重写toString方法,使用@Override注解标识
    @Override
    public String toString() {
        return "Person{姓名:" + name + ",年龄:" + age + ",性别:" + gender + "}";
    }
}

public class TestPerson {
    public static void main(String[] args) {
        Person p = new Person("赵六", 22, "男");
        System.out.println(p); // 直接打印对象,自动调用toString方法
    }
}

输出结果

复制代码
Person{姓名:赵六,年龄:22,性别:男}

注意@Override注解用于检查是否正确重写父类方法,可选但推荐使用,能避免拼写错误。

六、包:Java 的类组织方式

在实际开发中,会定义大量的类,为了避免类名冲突、提高代码的可读性和可维护性,Java 引入了包(Package),类似于文件系统中的目录,用于对类进行分层组织。

6.1 包的基本使用

(1)导入包中的类

Java 提供了大量的内置类(如DateArrayList),存放在不同的包中,使用时需要通过import语句导入:

  • 导入单个类:import 包名.类名;
  • 导入包下所有类:import 包名.*;
  • 静态导入:import static 包名.类名.静态成员;(直接导入静态方法 / 变量,无需类名调用)

示例

java 复制代码
// 导入java.util包下的Date类
import java.util.Date;
// 静态导入java.lang.Math的所有静态成员
import static java.lang.Math.*;

public class TestPackage {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date.getTime()); // 获取时间戳

        double x = 3, y = 4;
        double hypotenuse = sqrt(pow(x, 2) + pow(y, 2)); // 直接使用sqrt、pow,无需Math.
        System.out.println(hypotenuse); // 输出5.0
    }
}
(2)自定义包

在文件最顶部 使用package语句声明包名,遵循以下规则:

  1. 包名使用小写字母 ,用.分隔层级;
  2. 包名一般为公司域名的颠倒形式(如com.bytecode.demo),保证唯一性;
  3. 包名必须与项目的目录结构一致(如com.bytecode.demo对应目录com/bytecode/demo)。

示例

java 复制代码
// 声明包名,该类属于com.bytecode.demo包
package com.bytecode.demo;

public class MyClass {
    public void sayHello() {
        System.out.println("Hello, Package!");
    }
}

6.2 常见的内置包

Java 提供了大量常用的内置包,开发中经常用到的有:

  1. java.lang:系统基础类(StringObjectMath),自动导入 ,无需手动import
  2. java.util:工具类包(集合、日期、随机数),如ArrayListDateRandom
  3. java.io:输入输出流包,用于文件读写;
  4. java.net:网络编程包,用于 TCP/IP 通信;
  5. java.sql:数据库编程包,用于 JDBC 操作。

6.3 包的访问权限

包的访问权限由访问限定符 控制,未加任何修饰符的成员(默认权限),只能在同一个包中访问,跨包无法访问。

七、封装:面向对象的核心特性之一

面向对象有三大特性:封装、继承、多态 ,其中封装是类和对象阶段的核心。封装的本质是套壳屏蔽细节,将对象的属性和行为有机结合,隐藏内部实现细节,仅对外提供统一的访问接口,保证数据的安全性。

7.1 封装的实现方式

  1. 使用 **private** 修饰成员变量,使其成为私有成员,只能在当前类内部 访问,类外无法直接通过对象名.成员变量访问;
  2. 提供公共的getter/setter 方法,作为类外访问私有成员的接口,在方法中可添加数据校验逻辑,保证数据的合法性。

7.2 封装代码示例

java 复制代码
class Student {
    // 私有成员变量:类外无法直接访问
    private String name;
    private int age;
    private double score;

    // getter方法:获取私有成员变量的值
    public String getName() {
        return name;
    }

    // setter方法:设置私有成员变量的值,添加数据校验
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    // 年龄校验:必须大于0且小于150
    public void setAge(int age) {
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            System.out.println("年龄不合法!");
            this.age = 0; // 赋默认值
        }
    }

    public double getScore() {
        return score;
    }

    // 成绩校验:必须大于等于0且小于等于100
    public void setScore(double score) {
        if (score >= 0 && score <= 100) {
            this.score = score;
        } else {
            System.out.println("成绩不合法!");
            this.score = 0;
        }
    }

    // 公共方法:展示学生信息
    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
    }
}

// 测试封装
public class TestEncapsulation {
    public static void main(String[] args) {
        Student s = new Student();
        // 类外无法直接访问private成员,如下代码会编译报错
        // s.name = "张三";
        // s.age = -18;

        // 通过setter方法设置值,触发数据校验
        s.setName("张三");
        s.setAge(-18); // 输出:年龄不合法!
        s.setScore(105); // 输出:成绩不合法!
        s.showInfo(); // 输出:姓名:张三,年龄:0,成绩:0

        // 重新设置合法值
        s.setAge(18);
        s.setScore(90);
        s.showInfo(); // 输出:姓名:张三,年龄:18,成绩:90

        // 通过getter方法获取值
        System.out.println(s.getName()); // 输出:张三
    }
}

7.3 封装的好处

  1. 提高数据安全性:通过 setter 方法的校验逻辑,避免非法数据赋值;
  2. 降低代码耦合度:类的内部实现修改后,只要保持接口(getter/setter)不变,类外代码无需修改;
  3. 简化代码使用:隐藏内部复杂实现,类外只需通过统一接口操作对象,无需关注细节;
  4. 提高代码可维护性:数据的操作逻辑集中在 getter/setter 方法中,便于统一修改和维护。

7.4 Java 的四种访问限定符

Java 通过访问限定符 控制类成员的访问范围,实现封装的细粒度控制,共有四种访问限定符,访问范围从大到小依次为:public > protected > 默认(包访问权限) > private

访问限定符 同一类中 同一包中 不同包的子类中 不同包的非子类中
public ✔️ ✔️ ✔️ ✔️
protected ✔️ ✔️ ✔️
默认(无) ✔️ ✔️
private ✔️
说明protected的用法在继承章节详细讲解,现阶段核心掌握publicprivate,默认权限作为了解。

八、static 关键字:类的共享成员

在开发中,经常会遇到多个对象共享同一个属性 的场景(如所有学生共享同一个教室、所有员工共享同一个公司名称),如果为每个对象都存储一份该属性,会造成内存浪费。static关键字就是为了解决这个问题,修饰的成员属于,而非具体的对象,所有对象共享该成员。

8.1 static 修饰成员变量(静态成员变量)

(1)特性
  1. 属于 ,而非对象,存储在方法区,不占用对象的内存空间;
  2. 所有对象共享,一个对象修改后,其他对象访问的是修改后的值;
  3. 生命周期伴随类的一生(类加载时创建,类卸载时销毁);
  4. 访问方式:类名.静态变量名(推荐)或对象名.静态变量名(不推荐)。
(2)代码示例
java 复制代码
class Student {
    private String name; // 实例变量:每个对象独有
    private int age;
    public static String classRoom = "高一(1)班"; // 静态变量:所有对象共享

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",教室:" + classRoom);
    }
}

public class TestStatic {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 16);
        Student s2 = new Student("李四", 17);
        s1.showInfo(); // 输出:姓名:张三,年龄:16,教室:高一(1)班
        s2.showInfo(); // 输出:姓名:李四,年龄:17,教室:高一(1)班

        // 通过类名修改静态变量,所有对象共享
        Student.classRoom = "高一(2)班";
        s1.showInfo(); // 输出:姓名:张三,年龄:16,教室:高一(2)班
        s2.showInfo(); // 输出:姓名:李四,年龄:17,教室:高一(2)班
    }
}

8.2 static 修饰成员方法(静态成员方法)

静态方法属于类,用于操作静态成员变量,也可提供通用的工具方法(如Math.sqrt())。

(1)特性
  1. 属于,而非对象,无需实例化对象即可调用;
  2. 访问方式:类名.静态方法名(参数)(推荐)或对象名.静态方法名(参数)(不推荐);
  3. 静态方法中不能使用非静态成员 (包括非静态变量和非静态方法),也不能使用this关键字;
  4. 非静态方法中可以正常使用静态成员。
(2)代码示例
java 复制代码
class Student {
    private String name;
    private int age;
    public static String classRoom = "高一(1)班";

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 静态方法:操作静态变量
    public static void changeClassRoom(String newClass) {
        classRoom = newClass;
        // 静态方法中不能使用非静态成员,如下代码编译报错
        // System.out.println(name);
        // this.showInfo();
    }

    // 非静态方法:可以使用静态变量
    public void showInfo() {
        System.out.println("姓名:" + name + ",教室:" + classRoom);
    }

    // 静态工具方法
    public static int add(int a, int b) {
        return a + b;
    }
}

public class TestStaticMethod {
    public static void main(String[] args) {
        // 无需实例化对象,直接通过类名调用静态方法
        Student.changeClassRoom("高一(3)班");
        int sum = Student.add(10, 20);
        System.out.println(sum); // 输出30

        Student s = new Student("张三", 16);
        s.showInfo(); // 输出:姓名:张三,教室:高一(3)班
    }
}

8.3 静态成员的初始化

静态成员变量的初始化有两种方式,不推荐在构造方法中初始化(构造方法初始化实例成员):

  1. 就地初始化 :定义时直接赋值,如public static String classRoom = "高一(1)班";
  2. 静态代码块初始化:通过静态代码块为静态成员赋值,下文详细讲解。

九、代码块:对象与类的初始化补充

代码块是用{}包裹的一段代码,根据定义位置和修饰符的不同,分为普通代码块、实例代码块(构造块)、静态代码块,主要用于补充对象和类的初始化逻辑。

9.1 普通代码块

定义在方法内部的代码块,用于限定变量的作用域,避免变量名冲突,一般很少使用。

java 复制代码
public class TestCommonBlock {
    public static void main(String[] args) {
        {
            int a = 10;
            System.out.println(a); // 输出10
        }
        // 超出作用域,无法访问a,如下代码编译报错
        // System.out.println(a);
    }
}

9.2 实例代码块(构造块)

定义在类内部、无任何修饰符 的代码块,用于初始化实例成员变量 ,每次创建对象时都会执行,且执行顺序在构造方法之前

java 复制代码
class Person {
    private String name;
    private int age;

    // 实例代码块:初始化实例成员
    {
        this.name = "默认姓名";
        this.age = 0;
        System.out.println("实例代码块执行");
    }

    // 构造方法
    public Person() {
        System.out.println("无参构造执行");
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造执行");
    }

    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestInstanceBlock {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.showInfo();
        System.out.println("==========");
        Person p2 = new Person("张三", 20);
        p2.showInfo();
    }
}

输出结果

复制代码
实例代码块执行
无参构造执行
姓名:默认姓名,年龄:0
==========
实例代码块执行
有参构造执行
姓名:张三,年龄:20

9.3 静态代码块

定义在类内部、被 static 修饰 的代码块,用于初始化静态成员变量类加载时仅执行一次,无论实例化多少个对象,都只执行一次,且执行顺序在实例代码块之前。

(1)核心特性
  1. 类加载时执行,仅执行一次;
  2. 用于初始化静态成员变量,不能操作实例成员;
  3. 多个静态代码块按定义的先后顺序依次执行;
  4. 执行顺序:静态代码块 > 实例代码块 > 构造方法
(2)代码示例
java 复制代码
class Student {
    private String name;
    private int age;
    public static String classRoom;

    // 静态代码块1:初始化静态成员
    static {
        classRoom = "高一(1)班";
        System.out.println("静态代码块1执行");
    }

    // 静态代码块2:多个静态代码块按顺序执行
    static {
        System.out.println("静态代码块2执行,教室:" + classRoom);
    }

    // 实例代码块
    {
        this.name = "默认姓名";
        this.age = 0;
        System.out.println("实例代码块执行");
    }

    // 构造方法
    public Student() {
        System.out.println("构造方法执行");
    }
}

public class TestStaticBlock {
    public static void main(String[] args) {
        System.out.println("第一次实例化对象");
        Student s1 = new Student();
        System.out.println("==========");
        System.out.println("第二次实例化对象");
        Student s2 = new Student();
        System.out.println("教室:" + Student.classRoom);
    }
}

输出结果

复制代码
第一次实例化对象
静态代码块1执行
静态代码块2执行,教室:高一(1)班
实例代码块执行
构造方法执行
==========
第二次实例化对象
实例代码块执行
构造方法执行
教室:高一(1)班

分析:静态代码块在第一次实例化对象时执行,第二次实例化时不再执行,而实例代码块和构造方法每次实例化都执行。

十、总结

类和对象是 Java 面向对象编程的基础,核心知识点可归纳为以下几点:

  1. 类与对象 :类是对象的抽象模板,对象是类的具体实例,通过new实例化对象,通过.访问成员;
  2. this 关键字:指向调用当前方法的对象,用于区分同名形参和成员变量、调用成员方法和其他构造方法;
  3. 对象初始化:默认初始化(JVM 赋默认值)、就地初始化(声明时赋值)、构造方法初始化(自动调用,仅一次);
  4. 封装 :用private修饰成员变量,提供 getter/setter 接口,保证数据安全,降低耦合度;
  5. static 关键字:修饰的成员属于类,所有对象共享,静态方法不能使用非静态成员;
  6. 代码块 :静态代码块(类加载执行一次,初始化静态成员)、实例代码块(每次创建对象执行,初始化实例成员),执行顺序为静态代码块 > 实例代码块 > 构造方法
  7. :用于组织类,避免类名冲突,通过import导入包,package声明包名。

掌握这些知识点,就能轻松应对类和对象的基础开发,而面向对象的另外两大特性继承和多态,则是在类和对象的基础上进行的扩展,后续会继续讲解。建议大家结合代码示例反复练习,理解每个知识点的本质,而非死记硬背,这样才能真正掌握面向对象的编程思想。

相关推荐
习惯就好zz2 小时前
Qt Quick 系统托盘完整实践
开发语言·qt·qml·系统托盘·system tray·qapplication·qguiapplication
Arya_aa2 小时前
Java中的static
java
笨笨马甲2 小时前
Qt集成OpenCV
开发语言·qt
笨笨马甲2 小时前
Qt 工业机器视觉开发
开发语言·qt
咚为2 小时前
深入浅出 Rust FFI:从内存安全到二进制兼容
开发语言·安全·rust
北城笑笑2 小时前
Vue 100 ,Metaspace memory lack Error( 元空间内存不足 )
java·前端·javascript·vue
Han.miracle2 小时前
Spring IoC 与 DI 核心知识点综合测试题
java·前端·数据库
-杨豫2 小时前
JavaScript入门到精通全套资料,以及核心进阶ES6语法,API,js高级等基础知识和实战教程
开发语言·javascript·es6
婉然从物2 小时前
IDEA中plugins无法连接网络
java·ide·intellij-idea