Java面向对象三大特性:封装、继承、多态

发布于:2025-05-09 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、封装(Encapsulation)

1. 封装的概念

封装是面向对象编程的第一大特性,它指的是将数据和操作数据的方法绑定在一起,并对外部隐藏对象的内部实现细节。

2. 封装的核心原则

  • 私有化属性:使用private修饰类的成员变量
  • 公开方法:提供public的getter和setter方法
  • 控制访问:通过方法限制对属性的不合理访问

3. 封装的实现示例

public class Person {
    // 私有属性
    private String name;
    private int age;
    
    // 公开方法
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        if(name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("姓名不能为空");
        }
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if(age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄不合法");
        }
        this.age = age;
    }
}

4. 封装的优势

  • 提高安全性:防止外部代码直接修改对象内部状态
  • 易于维护:内部实现修改不影响外部调用
  • 增强可扩展性:可以在方法中添加额外逻辑(如验证)
  • 隐藏复杂性:使用者无需了解内部实现细节

二、继承(Inheritance)

1. 继承的概念

继承是面向对象编程的第二大特性,它允许一个类(子类)基于另一个类(父类)来构建,继承父类的属性和方法。

2. 继承的实现

// 父类
class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void eat() {
        System.out.println(name + "正在吃东西");
    }
}

// 子类
class Dog extends Animal {
    public Dog(String name) {
        super(name); // 调用父类构造方法
    }
    
    public void bark() {
        System.out.println("汪汪叫");
    }
}

3. 继承的特点

  • 单继承:Java只支持单继承(一个子类只能有一个直接父类)
  • 传递性:继承关系可以传递(A继承B,B继承C,则A也继承C)
  • 构造方法:子类构造方法必须先调用父类构造方法(super())
  • 方法重写:子类可以重写(override)父类的方法

4. 方法重写规则

  • 方法名、参数列表必须相同
  • 返回类型可以相同或是父类返回类型的子类
  • 访问权限不能比父类更严格
  • 不能抛出比父类更宽泛的异常

5. super关键字

  • super.成员变量:访问父类的成员变量
  • super.成员方法():调用父类的成员方法
  • super():调用父类的构造方法

三、多态(Polymorphism)

1. 多态的概念

多态是面向对象编程的第三大特性,它指的是同一操作作用于不同对象,可以有不同的解释,产生不同的执行结果

2. 多态的实现条件

  1. 继承关系:存在继承关系的类
  2. 方法重写:子类重写父类的方法
  3. 向上转型:父类引用指向子类对象

3. 多态的类型

(1) 编译时多态(方法重载)
class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
}
(2) 运行时多态(方法重写)
class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal myAnimal = new Cat(); // 向上转型
        myAnimal.makeSound(); // 输出"喵喵喵"
        
        myAnimal = new Dog(); // 向上转型
        myAnimal.makeSound(); // 输出"汪汪汪"
    }
}

4. 多态的应用场景

  • 接口回调:通过接口引用调用不同实现类的方法
  • 集合中的多态:List list = new ArrayList()
  • 方法参数多态:方法参数声明为父类类型,可接受所有子类对象

5. instanceof运算符

用于检查对象是否是特定类或其子类的实例

if (myAnimal instanceof Dog) {
    Dog myDog = (Dog) myAnimal; // 向下转型
    myDog.bark();
}

四、三大特性综合关系

  1. 封装是基础:封装数据和方法,形成独立的类
  2. 继承是手段:通过继承建立类之间的关系
  3. 多态是表现:通过多态展现不同对象的特性

五、常见面试问题

Q1: 重载(Overload)和重写(Override)的区别?

区别点 重载 重写
发生位置 同一个类中 父子类之间
方法名 相同 相同
参数列表 必须不同 必须相同
返回类型 可以不同 相同或是子类
访问修饰符 无限制 不能比父类更严格
异常 无限制 不能抛出更宽泛的异常

Q2: 为什么Java不支持多继承?

为了避免"菱形继承"问题(即一个类继承自两个具有相同方法的父类时产生的二义性)。Java通过接口实现类似多继承的功能。

Q3: 构造方法能否被重写?

不能。构造方法不是成员方法,不能被重写。子类构造方法必须调用父类构造方法(显式或隐式)。

六、最佳实践建议

  1. 封装原则

    • 所有属性尽量私有化
    • 只在必要时提供getter/setter
    • 在setter方法中添加验证逻辑
  2. 继承原则

    • 遵循"is-a"关系设计继承
    • 避免过深的继承层次(一般不超过3层)
    • 考虑使用组合代替继承
  3. 多态原则

    • 优先使用接口编程
    • 避免滥用instanceof
    • 方法参数尽量使用父类/接口类型

通过合理运用封装、继承和多态这三大特性,可以构建出高内聚、低耦合的面向对象程序,提高代码的可维护性和扩展性。


网站公告

今日签到

点亮在社区的每一天
去签到