一、对象与类的核心认知

1.1 对象的本质

对象是一种特殊的数据结构,用于承载一个事物的完整数据,从而在程序中对该事物进行具象化表达。

相较于变量、数组等基础数据存储结构,对象具备更强的结构化能力:可将一个事物的多维度属性与行为进行整合,实现数据与处理逻辑的一体化管理。例如对于影视演员这一事物,可通过对象承载其姓名、年龄、身高、体重等多维度属性;对于学生这一事物,可通过对象承载姓名、各科成绩等数据,同时内置成绩计算的相关行为。

1.2 类的核心定位

类也被称为对象的设计图或模板,是创建对象的基础。在Java中,必须先定义类,才能通过类创建对应的对象;每一次通过new关键字实例化类,都会得到一个全新的、独立的对象。

类的核心组成分为两部分:

  • 成员变量(属性):用来说明对象可存储的数据,描述事物的静态特征;
  • 成员方法(行为):描述对象具备的功能,即对数据可执行的处理操作。

二、类的基础语法与对象实例化

2.1 类的基础语法结构

/**
 * 学生类:作为创建学生对象的模板
 */
public class Student {
    // 成员变量:学生的属性
    String name;        // 姓名
    double chinese;     // 语文成绩
    double math;        // 数学成绩

    // 成员方法:计算并打印总成绩
    public void printTotalScore() {
        System.out.println(name + "同学的各科总分是:" + (chinese + math));
    }

    // 成员方法:计算并打印平均成绩
    public void printAverageScore() {
        System.out.println(name + "同学的各科平均分是:" + (chinese + math) / 2.0);
    }
}

2.2 对象的实例化与使用

通过new关键字完成类的实例化,得到对象后,可通过对象名.属性名访问成员变量,通过对象名.方法名()调用成员方法。

/**
 * 测试类:完成学生对象的创建与功能验证
 */
public class StudentTest {
    public static void main(String[] args) {
        // 实例化第一个学生对象并赋值
        Student s1 = new Student();
        s1.name = "播妞";
        s1.chinese = 100;
        s1.math = 100;
        // 调用对象的方法
        s1.printTotalScore();
        s1.printAverageScore();

        // 实例化第二个学生对象并赋值
        Student s2 = new Student();
        s2.name = "播仔";
        s2.chinese = 59;
        s2.math = 100;
        // 调用对象的方法
        s2.printTotalScore();
        s2.printAverageScore();
    }
}

程序执行结果:

播妞同学的各科总分是:200.0
播妞同学的各科平均分是:100.0
播仔同学的各科总分是:159.0
播仔同学的各科平均分是:79.5

2.3 对象的内存模型

Java程序运行时,对象的相关数据会分布在三个核心内存区域:

  1. 栈内存:存储对象的引用(地址),方法的局部变量,方法执行完毕后会自动释放;
  2. 堆内存:存储实例化对象的实际数据(成员变量),每一个new出来的对象都会在堆内存中分配独立的空间;
  3. 方法区:存储类的字节码信息,包括类的成员变量、成员方法定义,类加载时仅会加载一次。

三、构造器的定义与应用

3.1 构造器的核心作用

构造器是类的特殊成员方法,在对象通过new关键字创建时,会被自动调用,核心应用场景为完成对象成员变量的初始化赋值

3.2 构造器的语法规范

构造器的名称必须与类名完全一致,且无返回值类型声明(无需写void),基础语法如下:

public class Student {
    String name;
    int age;

    // 无参构造器
    public Student() {
    }

    // 有参构造器
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3.3 构造器的使用规则

  1. 类在定义时,会默认自带一个无参构造器,无需手动声明;
  2. 若为类显式定义了有参构造器,默认的无参构造器会自动失效,若需使用无参构造器,必须手动显式定义;
  3. 一个类可定义多个重载的构造器,根据参数列表的不同完成不同的初始化逻辑。

3.4 构造器的实战使用

public class ConstructorTest {
    public static void main(String[] args) {
        // 调用无参构造器创建对象,后续通过set方法赋值
        Student s1 = new Student();
        s1.name = "张三";
        s1.age = 20;

        // 调用有参构造器创建对象,同时完成初始化赋值
        Student s2 = new Student("李四", 22);
    }
}

四、this关键字的核心作用

4.1 this的本质

this是一个引用类型变量,存在于类的成员方法与构造器中,指向当前调用该方法的对象,即“哪个对象调用方法,this就指向哪个对象”。

4.2 核心应用场景

this的核心作用是解决成员变量与方法内局部变量的命名冲突问题。当方法内的局部变量与类的成员变量名称相同时,通过this.变量名的方式,显式指定访问的是类的成员变量。

public class Student {
    // 成员变量
    String name;
    double score;

    // 带参方法,局部变量与成员变量重名
    public void checkPass(double score) {
        // this.score 代表当前对象的成员变量score
        // score 代表方法传入的局部变量score
        if(this.score >= score) {
            System.out.println("成绩达标");
        } else {
            System.out.println("成绩未达标");
        }
    }
}

除此之外,this也可用于在构造器中调用本类的其他重载构造器,简化初始化代码。

五、封装特性的设计与实现

5.1 封装的核心定义

封装是面向对象编程的三大核心特征(封装、继承、多态)之一,其核心设计思想是:将事物的数据与处理数据的方法设计在同一个类的对象中,遵循合理隐藏、合理暴露的设计规范。

5.2 封装的代码实现

通过Java的访问权限修饰符,控制类成员的可见性,实现封装的设计规范:

  • 隐藏成员:使用private(私有)修饰符修饰成员变量,仅当前类内部可访问,外部类无法直接操作;
  • 暴露成员:使用public(公开)修饰符修饰成员方法,对外提供统一的访问与操作入口。

5.3 封装的设计优势

  1. 提升数据安全性,避免外部类直接修改成员变量,可在暴露的方法中增加数据校验逻辑;
  2. 规范数据的访问方式,降低代码耦合度;
  3. 隐藏代码的实现细节,仅对外暴露必要的功能入口。

封装后的标准类示例:

public class Student {
    // 私有成员变量:对外隐藏
    private String name;
    private double chinese;
    private double math;

    // 公开的get/set方法:对外暴露,提供访问入口
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getChinese() {
        return chinese;
    }

    public void setChinese(double chinese) {
        // 增加数据校验,确保成绩合法
        if(chinese >= 0 && chinese <= 100) {
            this.chinese = chinese;
        } else {
            System.out.println("语文成绩输入不合法,需在0-100之间");
        }
    }

    public double getMath() {
        return math;
    }

    public void setMath(double math) {
        if(math >= 0 && math <= 100) {
            this.math = math;
        } else {
            System.out.println("数学成绩输入不合法,需在0-100之间");
        }
    }

    // 公开的业务方法:对外暴露功能
    public void printTotalScore() {
        System.out.println(name + "同学的各科总分是:" + (chinese + math));
    }
}

六、JavaBean(实体类)规范与应用

6.1 JavaBean的核心规范

JavaBean是Java开发中约定俗成的实体类规范,是一种仅负责数据存取的特殊类,核心作用是实现数据与业务处理逻辑的分离,是MVC、分层开发架构的基础。

标准JavaBean需满足以下3个核心要求:

  1. 类中的所有成员变量必须使用private修饰实现私有化;
  2. 为每一个私有化的成员变量,提供public修饰的getter(取值)与setter(赋值)方法;
  3. 必须提供一个public修饰的无参构造器,有参构造器为可选定义。

6.2 标准JavaBean示例

/**
 * 教师实体类:标准JavaBean规范实现
 */
public class Teacher {
    // 私有成员变量
    private String name;
    private String workId;

    // 无参构造器(必须)
    public Teacher() {
    }

    // 有参构造器(可选)
    public Teacher(String name, String workId) {
        this.name = name;
        this.workId = workId;
    }

    // getter与setter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWorkId() {
        return workId;
    }

    public void setWorkId(String workId) {
        this.workId = workId;
    }

    // 成员方法
    public void teach() {
        System.out.println("工号为" + workId + "的" + name + "老师正在讲课");
    }
}

6.3 JavaBean的使用方式

public class TeacherTest {
    public static void main(String[] args) {
        // 方式1:无参构造器创建对象 + setter方法赋值
        Teacher t1 = new Teacher();
        t1.setName("杨老师");
        t1.setWorkId("t001");
        t1.teach();

        // 方式2:有参构造器创建对象,直接完成赋值
        Teacher t2 = new Teacher("李老师", "t002");
        t2.teach();
    }
}

6.4 应用场景

JavaBean实体类的对象仅负责数据的承载与存取,数据的业务处理逻辑由专门的业务类实现,从而实现数据与业务的解耦,提升代码的可维护性与可扩展性。

七、static关键字与静态成员

static意为静态,可用于修饰类的成员变量与成员方法,被修饰的成员属于类本身,而非类的实例对象,与类一起加载,无需创建对象即可访问。

7.1 静态成员变量(类变量)

7.1.1 核心定义与特性

成员变量根据是否被static修饰,分为两类:

类型定义核心特性访问方式
静态变量(类变量)static修饰的成员变量与类一起加载,内存中仅存在一份,被该类的所有实例对象共享推荐:类名.静态变量名
不推荐:对象.静态变量名
实例变量(对象变量)未被static修饰的成员变量属于每个独立的对象,每个对象都有一份独立副本,互不影响仅支持:对象.实例变量名

7.1.2 应用场景与代码示例

当某个数据仅需一份,且需要被所有对象共享访问、修改时,可定义为静态变量。典型场景:统计类的实例化对象总数。

public class User {
    // 静态变量:统计对象创建数量,被所有对象共享
    public static int userCount = 0;

    // 无参构造器:每创建一个对象,计数+1
    public User() {
        User.userCount++;
    }
}
public class StaticFieldTest {
    public static void main(String[] args) {
        // 类名直接访问静态变量
        System.out.println(User.userCount); // 输出:0

        // 创建3个对象
        new User();
        new User();
        new User();

        // 静态变量已被所有对象共享修改
        System.out.println(User.userCount); // 输出:3
    }
}

7.2 静态成员方法(类方法)

7.2.1 核心定义与特性

成员方法根据是否被static修饰,分为两类:

类型定义核心特性访问方式
静态方法(类方法)static修饰的成员方法属于类本身,无需创建对象即可调用推荐:类名.静态方法名
不推荐:对象.静态方法名
实例方法(对象方法)未被static修饰的成员方法属于对象,必须创建实例对象后才能调用仅支持:对象.实例方法名

7.2.2 核心应用场景:工具类设计

静态方法的核心应用场景是开发工具类。工具类是一种通用功能类,其中的方法均为静态方法,每个方法完成一个通用功能,可直接被开发者调用,无需创建工具类的对象。

工具类设计的核心优势:

  1. 提高代码复用性,通用功能可全局调用;
  2. 调用便捷,无需实例化对象,直接通过类名调用;
  3. 节省内存,避免创建大量仅用于调用方法的对象。

7.2.3 工具类设计规范与示例

工具类无需创建对象,建议将构造器私有化,避免被外部类实例化。

/**
 * 字符串工具类:静态方法实现通用功能
 */
public class StringUtil {
    // 私有化构造器:禁止外部实例化
    private StringUtil() {
    }

    // 静态方法:判断字符串是否为空
    public static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }

    // 静态方法:判断邮箱格式是否合法
    public static boolean isEmail(String email) {
        if(isEmpty(email)) {
            return false;
        }
        return email.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
    }
}

工具类的使用:

public class UtilTest {
    public static void main(String[] args) {
        // 直接通过类名调用静态方法,无需创建对象
        System.out.println(StringUtil.isEmpty("")); // 输出:true
        System.out.println(StringUtil.isEmail("test@163.com")); // 输出:true
    }
}

7.3 静态成员的访问注意事项

  1. 静态方法中可以直接访问静态成员,无法直接访问实例成员
  2. 实例方法中既可以直接访问静态成员,也可以直接访问实例成员;
  3. 实例方法中可以使用this关键字,静态方法中不允许使用this关键字

八、实战案例:简易电影信息展示系统

8.1 需求说明

  1. 展示系统中的全部电影信息(每部电影展示名称、价格);
  2. 支持根据电影编号(id)查询对应电影的详细信息。

8.2 代码实现

步骤1:定义电影实体类(JavaBean)

public class Movie {
    // 私有成员变量
    private int id;         // 电影编号
    private String name;    // 电影名称
    private double price;   // 电影票价
    private String director;// 导演
    private String cast;    // 主演
    private double score;   // 电影评分

    // 无参构造器
    public Movie() {
    }

    // 有参构造器
    public Movie(int id, String name, double price, String director, String cast, double score) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.director = director;
        this.cast = cast;
        this.score = score;
    }

    // getter与setter方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getCast() {
        return cast;
    }

    public void setCast(String cast) {
        this.cast = cast;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}

步骤2:定义电影业务处理类

public class MovieOperator {
    private Movie[] movies;

    // 构造器:传入电影数据数组
    public MovieOperator(Movie[] movies) {
        this.movies = movies;
    }

    // 功能1:展示全部电影的名称与价格
    public void showAllMovies() {
        System.out.println("===== 系统全部电影信息 =====");
        for (Movie movie : movies) {
            System.out.println("电影名称:" + movie.getName() + ",票价:" + movie.getPrice() + "元");
        }
    }

    // 功能2:根据电影编号查询电影详情
    public void queryMovieById(int id) {
        for (Movie movie : movies) {
            if(movie.getId() == id) {
                System.out.println("===== 电影详情信息 =====");
                System.out.println("电影编号:" + movie.getId());
                System.out.println("电影名称:" + movie.getName());
                System.out.println("电影评分:" + movie.getScore());
                System.out.println("电影票价:" + movie.getPrice() + "元");
                System.out.println("导演:" + movie.getDirector());
                System.out.println("主演:" + movie.getCast());
                return;
            }
        }
        System.out.println("未查询到编号为" + id + "的电影信息");
    }
}

步骤3:测试主类,实现功能调用

public class MovieSystem {
    public static void main(String[] args) {
        // 1. 初始化电影数据
        Movie[] movies = new Movie[3];
        movies[0] = new Movie(1, "长津湖之水门桥", 45.0, "徐克", "吴京、易烊千玺", 9.6);
        movies[1] = new Movie(2, "一点就到家", 38.0, "许宏宇", "刘昊然、彭昱畅", 8.7);
        movies[2] = new Movie(3, "月球陨落", 52.0, "罗兰·艾默里奇", "哈莉·贝瑞", 7.9);

        // 2. 创建业务处理对象
        MovieOperator operator = new MovieOperator(movies);

        // 3. 调用功能1:展示全部电影信息
        operator.showAllMovies();

        // 4. 调用功能2:根据编号查询电影详情
        operator.queryMovieById(2);
        operator.queryMovieById(5);
    }
}

8.3 程序执行结果

===== 系统全部电影信息 =====
电影名称:长津湖之水门桥,票价:45.0元
电影名称:一点就到家,票价:38.0元
电影名称:月球陨落,票价:52.0元
===== 电影详情信息 =====
电影编号:2
电影名称:一点就到家
电影评分:8.7
电影票价:38.0元
导演:许宏宇
主演:刘昊然、彭昱畅
未查询到编号为5的电影信息

标签: none

添加新评论