面向对象编程(oop)是java的灵魂。理解类和对象,就如同掌握了构建java程序的基石。本文将带你从零开始,深入理解类的定义,对象的创建与初始化,再到封装,包,static关键字以及代码块等核心概念。

目录

引言:从“洗衣服”看编程范式的演变

一.类和对象的定义与初始化

        1.1类是什么?对象是什么?

        1.2类的定义格式

        1.3对象的实例化和访问

二. this引用与构造方法

        2.1this关键字:解决“我是谁”

        2.2构造方法:对象的“出生证明”

        2.3默认构造器的陷阱

        2.4构造方法重载

三.封装与包管理

        3.1封装:拒绝“裸奔”的数据

        3.2访问限定符:权限的围栏

        3.3包(package):代码的“文件管理系统”

四.static关键字与代码块

        4.1static修饰成员变量(类变量)

        4.2static修饰成员方法(类方法)

        4.3代码块 

五.对象的打印——重写toString

总结


引言:从“洗衣服”看编程范式的演变

        核心观点:代码不仅仅是逻辑的堆砌,更是对现实世界的抽象。

面向过程:关注步骤。放水-->加洗衣粉-->搅拌-->脱水-->。如果中途洗衣机坏了,或者要洗鞋子,整个流程就要重写。代码耦合度极高,扩展和维护非常困难。

面向对象:关注参与者——人,洗衣机,,洗衣粉。人不需要知道洗衣机内部涡轮怎么转,只需要调用washingMachine.start()。这就是解耦,也是软件设计的核心目标之一。

        拓展:在现在,这种思想依然适用。每个对象就像是一个独立的微服务,我们通过接口(api)进行交互,不需要关系对方内部是用java还是go写的。面向对象的基本原则——封装,继承,多态——在分布式系统中同样适用。

一.类和对象的定义与初始化

        1.1类是什么?对象是什么?

        类:是对现实世界实体的抽象描述,相当于一张设计图纸,它规定了给实体有哪些属性(如品牌,尺寸)和哪些功能(如洗衣脱水)。

        对象:根据图纸实例化出来的具体东西,真正存在于内存中。

内存视角:定义一个class时,JVM只是在方法区记录了这个类的结构,并没有分配存储数据的空间。当使用new关键字实例化对象时,JVM才会在堆内存中开辟空间存储具体数据。

        1.2类的定义格式

class ClassName{
    //成员变量(属性)
    //成员方法(行为)
}


    //洗衣机类示例
class WashMachine {
    // 成员变量
    public String brand;   // 品牌
    public String type;    // 型号
    public double weight;  // 重量
    public String color;   // 颜色

    // 成员方法
    public void washClothes() {
        System.out.println("洗衣功能");
    }
    public void dryClothes() {
        System.out.println("脱水功能");
    }
}

命名规范:类名使用大驼峰,方法和变量使用小驼峰。

        1.3对象的实例化和访问

        使用new关键字创建对象,通过对象引用.成员进行访问。

public class Main{
    public static void main(String[] args){
        WashMachine wm=new WashMachine();//实例化
        wm.brand="海尔";
        wm.washClothes();    //调用方法
    }    
}

二. this引用与构造方法

        2.1this关键字:解决“我是谁”

        当形参和成员变量名相同时,你需要使用this来区分。this指向当前对象的引用

public void setDay(int year, int month, int day) {
    this.year = year;   // this.year 是成员变量,右边的 year 是形参
    this.month = month;
    this.day = day;
}

        2.2构造方法:对象的“出生证明”

        构造方法是一种特殊的成员方法:

                方法名必须和类名相同

                没有返回值类型(void也不能写)

                创建对象时,由编译器自动调用,且在整个生命周期中只调用一次

public class Date {
    public int year, month, day;

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

        2.3默认构造器的陷阱

        如果用户没有定义任何构造方法,编译器会默认生成一个无参构造方法。

        而一旦手动定义了带参数的构造方法,编译器就不会提供默认的无参构造器。

很多框架在通过反射创建对象时,往往依赖无参构造器。如果只写了有参构造器,这些框架就会报错——可以显式提供一个无参构造方法

        2.4构造方法重载

        可以定义多个构造方法,参数列表不同

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

三.封装与包管理

        3.1封装:拒绝“裸奔”的数据

        封装是面向对象的三大特性之一。它通过private隐藏成员变量,对外提供public的getter//setter方法作为访问接口。

class Student {
    private String name;
    private int age;

    public String getNmae(){
        return name ;
    }//获取name
    
    public void setNmae(String name){
        this.name=name;
    }//传入name

    public int getAge(){
        return age;
    }//获取age

    public void setAge(int age){
        if(age>=0&&age<=100){
                this.age=age;
            }else{
                System.out.println("年龄非法");
            }
    }
}

        封装的核心价值:

控制:在setter中可以加入校验逻辑,防止外部直接给年龄赋值-10这样的非法数据

隐藏:内部实现可以随时修改,只要对外接口不变,调用方就不要改动。

        3.2访问限定符:权限的围栏

java提供了四种访问权限(由小到大)

修饰符 private (default) protected public
本类
同包
子类
任意位置
典型场景

对象内部的私有状态

(如银行卡密码)

包级工具类

(仅限内部使用)

父类留给子类

扩展的钩子方法

对外暴露的api接口

        3.3包(package):代码的“文件管理系统”

概念:包是一种组织类的方式,类似于文件系统的目录。它用于便面类名冲突,控制访问权限,更好的组织代码。

导入包:使用import语句可以简化类的使用。如果发生命名冲突,使用全限定类名(如java.util.Date)。

四.static关键字与代码块

        4.1static修饰成员变量(类变量)

当某个属性被所有对象共享时,使用static修饰。例如所有学生所在的教室。

class Student {
    private String name;
    public static String classRoom = "1-101";   // 静态成员变量
}

特性:

        属于类,不属于任何一个对象,所有对象共享一份

        存储在方法区,而实例变量存储在堆中——这是它们生命周期不同的根本原因。

        可以通过类名.静态变量直接访问,也可以通过实例对象访问

        生命周期:随类加载而创建,随类卸载而销毁。

为什么工具类中的方法通常是静态的?

        比如Math.sqrt()不需要依赖某个具体的Math对象,它是通用的逻辑,所以设计为静态方法,可以直接通过类名调用。

        4.2static修饰成员方法(类方法)

class Student {
    private static String classRoom = "1-101";
    public static String getClassRoom() {
        return classRoom;
    }
}

// 调用
Student.getClassRoom();

        静态方法的重要限制:

不能访问非静态成员变量

不能调用非静态方法

不能使用this关键字(因为没有当前对象)

        4.3代码块 

                1.普通代码块:定义在方法内部,用于限定变量作用域。

                2.实例代码块(构造代码块)

定义在类中,方法外,不加任何修饰符。每次创建对象时都会执行,并且在构造方法之前执行。常用于通用的初始化逻辑。

                3.静态代码块:使用static修饰,定义在类中方法外。在类加载时执行一次,常用于初始化成员变量。

class Student{
    private static String classRoom;

    //静态代码块
    static{
        classRoom="1";
        System.out.println("静态代码块执行");//加载类时执行一次
    }

    //实例代码块
    {
        System.out.println("实例代码块执行");//每次实例化对象执行一次
    }

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

当父类和子类都有代码块

顺序:父类静态块——>子类静态块——>父类实例块——>父类构造方法——>子类实例块——>子类构造方法

五.对象的打印——重写toString

直接打印对象引用,输出的是类名@哈希码。如果想打印对象的属性内容,需要重写toString方法

@Override
public String toString() {
    return "[" + name + ", " + gender + ", " + age + "]";
}

总结

1.类与对象:类是对象的模板,对象是类的实例,通过new关键字创建。

2.成员变量和成员方法:属性描述状态,方法定义行为。

3.构造方法:与类同名,无返回值,用于初始化对象;一旦自定义构造方法,编译器不再提供默认无参构造。

4.this引用:指向当前对象,用于区分成员变量和局部变量,也是成员方法的隐藏参数。

5.封装:使用private隐藏属性,通过public的getter/setter控制访问,提高安全性和可维护性。

6.包:组织类,防止命名冲突,控制访问权限。

7.static关键字:静态成员属于类级别,所有对象共享;静态方法不能访问非静态成员。

8.代码块:静态代码块(类加载时执行一次),实例代码块(创建对象时执行),普通代码块(方法内局部作用域)

9.对象的打印:重写toString方法可以自定义输出。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐