一、封装

1. 为什么要有封装?

问题示例:

public class PrivateTest {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.legs = -3;  // 不合理的赋值
        animal.move();     // 输出:动物用 -3 条腿走路...
    }
}

class Animal {
    int legs;  // 属性直接暴露,可被任意修改
    
    public void move() {
        System.out.println("动物用" + legs + "条腿走路...");
    }
}

封装的目的:

  • 将对象的属性和实现细节隐藏,只对外提供公共的访问方式

  • 提高代码的安全性:防止属性被随意修改

  • 提高代码的维护性:内部实现修改不影响外部调用

  • 原则:该隐藏的隐藏,该暴露的暴露

2. 访问修饰符

修饰符

同类

同包

子类

不同包

说明

public

公共访问

protected

受保护访问

默认

包内访问

private

类内访问

3. 属性封装示例

class Animal {
    // 隐藏属性:private修饰
    private int legs;
    private String name;
    
    // 暴露公共的setter方法,控制属性的赋值
    public void setLegs(int legs) {
        if (legs == 2 || legs == 4) {  // 数据校验
            this.legs = legs;
        } else {
            System.out.println("腿的数量不合法!");
        }
    }
    
    // 暴露公共的getter方法
    public int getLegs() {
        return legs;
    }
}

4. 方法封装示例

class Car {
    private int speed;
    
    // 隐藏内部实现细节
    private void changeMeter() {
        // 更新码表显示
    }
    
    private void changeSpeed(int delta) {
        this.speed += delta;
    }
    
    // 暴露公共接口
    public void changeGear(int gear) {
        changeMeter();           // 内部调用
        changeSpeed(gear * 10);  // 内部调用
        System.out.println("当前速度:" + speed);
    }
}

二、继承

1. 为什么需要继承?

场景分析:

人(父类)
     ↙      ↓       ↘
  学生     老师      工人
  • 学生、老师、工人都有人的基本属性和行为

  • 每个子类又有自己特有的属性和方法

  • 继承可避免代码冗余,提高复用性

2. 继承语法

// 父类
class Person {
    String name;
    int age;
    String gender;
    
    public void eat() {
        System.out.println("吃饭");
    }
}

// 子类继承父类
class Student extends Person {
    String studentId;
    
    public void study() {
        System.out.println("学习");
    }
}

3. 方法重写(Override)

class Animal {
    public void move() {
        System.out.println("动物移动");
    }
}

class Dog extends Animal {
    // 重写父类方法
    @Override
    public void move() {
        System.out.println("狗用四条腿跑");
    }
}

4. 重写 vs 重载

区别点

重写(Override)

重载(Overload)

范围

子类继承父类

同一个类内部

场景

业务延伸,方法改进

同一个功能,参数不同

语法

同名、同参数、同返回类型

同名、不同参数列表

访问权限

不能更严格(可更宽松)

无限制

5. super关键字

class Father {
    int age = 40;
    
    public Father() {
        System.out.println("父类构造方法");
    }
    
    public void show() {
        System.out.println("父类方法");
    }
}

class Son extends Father {
    int age = 20;
    
    public Son() {
        super();  // 调用父类构造方法(可省略)
    }
    
    public void display() {
        System.out.println("子类年龄:" + age);
        System.out.println("父类年龄:" + super.age);  // 访问父类属性
        super.show();  // 调用父类方法
    }
}

6. final关键字

final的作用:

  • 修饰类:不能被继承(如String类)

  • 修饰方法:不能被重写

  • 修饰变量:变为常量,不可修改

// final修饰类
final class FinalClass {
    // 不能被继承
}

// final修饰方法
class Base {
    public final void finalMethod() {
        // 不能被子类重写
    }
}

// final修饰变量
class Circle {
    public final double PI = 3.14159;  // 常量
    // PI = 3.15;  // 错误!不能修改
}

三、多态

1. 为什么要有多态?

问题代码:

class ZooKeeper {
    // 需要为每种动物写一个feed方法
    public void feed(Dog dog) {
        dog.eat();
    }
    
    public void feed(Cat cat) {
        cat.eat();
    }
    
    public void feed(Lion lion) {
        lion.eat();
    }
    // ... 需要无数个重载方法
}

多态解决方案:

class ZooKeeper {
    // 一个方法搞定所有动物
    public void feed(Animal animal) {
        animal.eat();  // 运行时根据实际对象类型调用对应方法
    }
}

2. 什么是多态?

多态定义:​ 父类引用指向子类对象

语法:

父类类型 对象名 = new 子类类型();

示例:

// 父类引用指向子类对象
Animal animal1 = new Dog();  // 多态
Animal animal2 = new Cat();  // 多态

// 只能调用父类中声明的方法
// 实际执行的是子类重写的方法
animal1.eat();  // 执行Dog的eat方法
animal2.eat();  // 执行Cat的eat方法

3. instanceof运算符

public void showAnimal(Animal animal) {
    animal.eat();
    
    // 类型判断
    if (animal instanceof Dog) {
        Dog dog = (Dog) animal;  // 向下转型
        dog.watchHouse();  // 调用Dog特有方法
    } else if (animal instanceof Cat) {
        Cat cat = (Cat) animal;  // 向下转型
        cat.catchMouse();  // 调用Cat特有方法
    }
}

总结

特性

核心思想

主要作用

实现方式

封装

隐藏细节,暴露接口

提高安全性、可维护性

private、getter/setter

继承

代码复用,扩展功能

避免重复代码,实现层次结构

extends、super

多态

统一接口,不同实现

提高扩展性,降低耦合

父类引用、方法重写

掌握面向对象这三大特性,是Java编程的基础,也是写出高质量代码的关键。在实际开发中,要灵活运用这些特性,设计出高内聚、低耦合的程序结构。

Logo

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

更多推荐