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

一、封装 (Encapsulation)

  1. 基本概念

· 将数据(属性)和操作数据的方法(行为)捆绑在一起

· 隐藏对象的内部实现细节,仅对外提供公共接口

  1. 实现方式

a. 访问修饰符

```java

public class BankAccount {

// 私有字段 - 完全封装

private double balance;

private String accountNumber;

// 公共方法 - 对外接口

public void deposit(double amount) {

if (amount > 0) {

balance += amount;

}

}

public boolean withdraw(double amount) {

if (amount > 0 && balance >= amount) {

balance -= amount;

return true;

}

return false;

}

// Getter方法 - 受控访问

public double getBalance() {

return balance;

}

}

```

b. 封装的好处

  1. 数据保护:防止外部直接修改内部数据

  2. 实现隐藏:修改内部实现不影响外部调用

  3. 提高安全性:通过验证逻辑保护数据完整性

  4. 降低耦合:外部只依赖接口,不依赖实现

  5. 设计原则

· 最小化访问权限:使用最严格的访问级别

· 不变性:尽可能使对象不可变

· 防御性拷贝:返回集合或对象的副本

```java

public class Person {

private final String name; // final确保不可变

private final Date birthDate;

public Person(String name, Date birthDate) {

this.name = name;

// 防御性拷贝

this.birthDate = new Date(birthDate.getTime());

}

public Date getBirthDate() {

// 返回副本而不是原始引用

return new Date(birthDate.getTime());

}

}

```

二、继承 (Inheritance)

  1. 基本概念

· 子类继承父类的属性和方法

· 实现代码复用和层次关系

  1. 继承类型

a. 单继承

```java

// 父类(基类)

class Vehicle {

protected String brand;

protected int maxSpeed;

public void start() {

System.out.println("Vehicle starting...");

}

}

// 子类(派生类)

class Car extends Vehicle {

private int numDoors;

public Car(String brand, int maxSpeed, int numDoors) {

this.brand = brand;

this.maxSpeed = maxSpeed;

this.numDoors = numDoors;

}

// 方法重写

@Override

public void start() {

System.out.println("Car starting with key...");

}

// 子类特有方法

public void openDoors() {

System.out.println("Opening " + numDoors + " doors");

}

}

```

b. 多继承(通过接口)

```java

interface Flyable {

void fly();

}

interface Swimmable {

void swim();

}

class AmphibiousVehicle extends Vehicle implements Flyable, Swimmable {

@Override

public void fly() {

System.out.println("Flying in the air");

}

@Override

public void swim() {

System.out.println("Swimming in water");

}

}

```

  1. 继承中的关键概念

a. super关键字

```java

class Parent {

protected String name;

public Parent(String name) {

this.name = name;

}

public void display() {

System.out.println("Parent: " + name);

}

}

class Child extends Parent {

private int age;

public Child(String name, int age) {

super(name); // 调用父类构造器

this.age = age;

}

@Override

public void display() {

super.display(); // 调用父类方法

System.out.println("Child age: " + age);

}

}

```

b. 构造器调用链

```java

class A {

public A() {

System.out.println("A constructor");

}

}

class B extends A {

public B() {

// 隐式调用super()

System.out.println("B constructor");

}

}

class C extends B {

public C() {

// 隐式调用super()

System.out.println("C constructor");

}

}

// 创建C对象输出:

// A constructor

// B constructor

// C constructor

```

  1. 继承的设计原则

· 里氏替换原则:子类必须能够替换父类

· 优先使用组合而非继承:减少继承的脆弱性

· 避免深度继承:建议不超过3层

三、多态 (Polymorphism)

  1. 编译时多态(静态绑定)

a. 方法重载

```java

class MathOperations {

// 参数类型不同

public int add(int a, int b) {

return a + b;

}

public double add(double a, double b) {

return a + b;

}

// 参数个数不同

public int add(int a, int b, int c) {

return a + b + c;

}

}

```

  1. 运行时多态(动态绑定)

a. 方法重写

```java

abstract class Shape {

protected String color;

public Shape(String color) {

this.color = color;

}

// 抽象方法 - 必须由子类实现

public abstract double area();

// 具体方法 - 子类可以重写

public void display() {

System.out.println("Shape color: " + color);

}

}

class Circle extends Shape {

private double radius;

public Circle(String color, double radius) {

super(color);

this.radius = radius;

}

@Override

public double area() {

return Math.PI * radius * radius;

}

@Override

public void display() {

System.out.println("Circle: radius=" + radius + ", color=" + color);

}

}

class Rectangle extends Shape {

private double width, height;

public Rectangle(String color, double width, double height) {

super(color);

this.width = width;

this.height = height;

}

@Override

public double area() {

return width * height;

}

@Override

public void display() {

System.out.println("Rectangle: " + width + "x" + height + ", color=" + color);

}

}

```

b. 多态使用

```java

public class TestPolymorphism {

public static void main(String[] args) {

// 向上转型

Shape shape1 = new Circle("Red", 5.0);

Shape shape2 = new Rectangle("Blue", 4.0, 6.0);

// 多态调用

shape1.display(); // 调用Circle的display()

System.out.println("Area: " + shape1.area());

shape2.display(); // 调用Rectangle的display()

System.out.println("Area: " + shape2.area());

// 多态在集合中的应用

List<Shape> shapes = new ArrayList<>();

shapes.add(new Circle("Green", 3.0));

shapes.add(new Rectangle("Yellow", 2.0, 4.0));

for (Shape shape : shapes) {

shape.display();

System.out.println("Area: " + shape.area());

}

}

}

```

四、三大特征的关系与协作

  1. 协同工作示例

```java

// 封装:隐藏内部实现

abstract class Employee {

private String name;

private int id;

public Employee(String name, int id) {

this.name = name;

this.id = id;

}

// 封装getter方法

public String getName() { return name; }

public int getId() { return id; }

// 抽象方法 - 多态的基础

public abstract double calculateSalary();

// 具体方法

public void displayInfo() {

System.out.println("ID: " + id + ", Name: " + name);

}

}

// 继承:复用基类代码

class FullTimeEmployee extends Employee {

private double monthlySalary;

public FullTimeEmployee(String name, int id, double monthlySalary) {

super(name, id);

this.monthlySalary = monthlySalary;

}

// 多态:重写计算方法

@Override

public double calculateSalary() {

return monthlySalary;

}

}

class PartTimeEmployee extends Employee {

private double hourlyRate;

private int hoursWorked;

public PartTimeEmployee(String name, int id, double hourlyRate, int hoursWorked) {

super(name, id);

this.hourlyRate = hourlyRate;

this.hoursWorked = hoursWorked;

}

@Override

public double calculateSalary() {

return hourlyRate * hoursWorked;

}

}

class ContractEmployee extends Employee {

private double contractAmount;

public ContractEmployee(String name, int id, double contractAmount) {

super(name, id);

this.contractAmount = contractAmount;

}

@Override

public double calculateSalary() {

return contractAmount;

}

}

// 使用三大特征

public class PayrollSystem {

private List<Employee> employees;

public PayrollSystem() {

employees = new ArrayList<>();

}

public void addEmployee(Employee employee) {

employees.add(employee);

}

// 多态:统一处理不同类型的员工

public void processPayroll() {

for (Employee emp : employees) {

emp.displayInfo();

double salary = emp.calculateSalary(); // 动态绑定

System.out.println("Salary: $" + salary);

System.out.println("---");

}

}

public static void main(String[] args) {

PayrollSystem payroll = new PayrollSystem();

// 添加不同类型的员工

payroll.addEmployee(new FullTimeEmployee("Alice", 101, 5000));

payroll.addEmployee(new PartTimeEmployee("Bob", 102, 20, 80));

payroll.addEmployee(new ContractEmployee("Charlie", 103, 3000));

// 统一处理

payroll.processPayroll();

}

}

```

  1. 设计模式中的应用

a. 模板方法模式

```java

// 封装算法框架

abstract class DataProcessor {

// 模板方法 - 定义算法骨架

public final void process() { // final防止子类修改算法结构

loadData();

transformData();

saveData();

cleanup();

}

// 具体步骤 - 部分由子类实现

protected abstract void loadData();

protected abstract void transformData();

// 默认实现

protected void saveData() {

System.out.println("Saving data to database...");

}

protected void cleanup() {

System.out.println("Cleaning up resources...");

}

}

// 继承和多态

class CSVProcessor extends DataProcessor {

@Override

protected void loadData() {

System.out.println("Loading CSV data...");

}

@Override

protected void transformData() {

System.out.println("Transforming CSV data...");

}

}

class XMLProcessor extends DataProcessor {

@Override

protected void loadData() {

System.out.println("Loading XML data...");

}

@Override

protected void transformData() {

System.out.println("Transforming XML data...");

}

@Override

protected void saveData() { // 重写保存方式

System.out.println("Saving data to cloud storage...");

}

}

```

五、面向对象设计原则

  1. SOLID原则

· S - 单一职责原则:一个类只负责一个功能领域

· O - 开闭原则:对扩展开放,对修改关闭

· L - 里氏替换原则:子类必须能替换父类

· I - 接口隔离原则:使用多个专门的接口

· D - 依赖倒置原则:依赖抽象,不依赖具体

  1. 结合三大特征的应用

```java

// 依赖倒置示例

interface MessageSender {

void send(String message);

}

// 具体实现

class EmailSender implements MessageSender {

@Override

public void send(String message) {

System.out.println("Sending email: " + message);

}

}

class SMSSender implements MessageSender {

@Override

public void send(String message) {

System.out.println("Sending SMS: " + message);

}

}

// 高层模块依赖抽象

class NotificationService {

private MessageSender sender;

// 依赖注入

public NotificationService(MessageSender sender) {

this.sender = sender;

}

public void notifyUser(String message) {

sender.send(message); // 多态调用

}

}

// 使用

NotificationService emailService = new NotificationService(new EmailSender());

NotificationService smsService = new NotificationService(new SMSSender());

```

六、常见面试问题

  1. 三大特征的区别与联系

· 封装是基础,隐藏实现细节

· 继承是手段,实现代码复用

· 多态是目的,提高灵活性

  1. 为什么说多态是面向对象的核心?

· 提高代码扩展性

· 实现接口统一

· 支持运行时动态绑定

  1. 继承 vs 组合

```java

// 继承 - "is-a"关系

class Car extends Vehicle { }

// 组合 - "has-a"关系

class Car {

private Engine engine; // 组合

private List<Wheel> wheels; // 聚合

}

```

  1. 如何选择继承还是实现接口?

· 需要共享代码:使用继承

· 需要定义行为规范:使用接口

· 需要多继承:使用接口

七、实际开发建议

  1. 封装建议

· 所有字段设为private

· 使用final修饰不可变字段

· 提供必要的getter/setter

· 考虑使用建造者模式处理复杂对象

  1. 继承建议

· 遵循里氏替换原则

· 避免超过3层的继承深度

· 优先考虑组合而非继承

· 考虑使用抽象类定义模板

  1. 多态建议

· 面向接口编程

· 使用工厂模式创建对象

· 考虑策略模式替换条件语句

总结

面向对象三大特征构成了面向对象编程的核心:

  1. 封装:保护内部状态,提供稳定接口

  2. 继承:实现代码复用,建立类层次关系

  3. 多态:提供灵活性,支持运行时动态行为

三者相辅相成,共同支撑起面向对象的设计思想。在实际开发中,应该根据具体场景灵活运用这些特征,遵循面向对象设计原则,构建出高内聚、低耦合、可维护、可扩展的软件系统。

相关推荐
寻寻觅觅☆7 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
YJlio7 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
偷吃的耗子7 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
l1t7 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
青云计划8 小时前
知光项目知文发布模块
java·后端·spring·mybatis
赶路人儿8 小时前
Jsoniter(java版本)使用介绍
java·开发语言
化学在逃硬闯CS8 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar1238 小时前
C++使用format
开发语言·c++·算法
山塘小鱼儿8 小时前
本地Ollama+Agent+LangGraph+LangSmith运行
python·langchain·ollama·langgraph·langsimth