第一章:封装的艺术 ------ 保护你的宝藏
案例分析:银行账户系统
想象一下,你正在构建一个银行账户系统。每个账户都有一个余额,这个余额需要受到严格的保护,不能被随意修改。我们可以通过封装来实现这一目标。
示例代码:
java
public class BankAccount {
private double balance; // 私有变量,不允许直接访问
public BankAccount(double initialBalance) {
if (initialBalance > 0.0) {
balance = initialBalance;
} else {
balance = 0.0;
}
}
// 提供公共方法存款
public void deposit(double amount) {
if (amount > 0.0) {
balance += amount;
}
}
// 提供公共方法取款
public boolean withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
return true;
} else {
return false;
}
}
// 提供公共方法查询余额
public double getBalance() {
return balance;
}
}
在这个例子中,balance
被声明为私有变量,只能通过deposit()
、withdraw()
和getBalance()
方法进行访问和修改。这样,我们就能确保账户的安全性和一致性。
第二章:继承的传承 ------ 父亲的衣钵
案例分析:动物王国
在Java中,继承允许我们创建一个类族谱,使得子类可以继承父类的属性和方法,从而实现代码的复用和扩展。
示例代码:
java
// 定义一个父类 Animal
public abstract class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void makeSound(); // 抽象方法,强制子类实现
}
// 定义一个子类 Dog,继承自 Animal
public class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
@Override
public void makeSound() {
System.out.println("Woof woof!");
}
}
// 定义另一个子类 Cat,继承自 Animal
public class Cat extends Animal {
public Cat(String name, int age) {
super(name, age);
}
@Override
public void makeSound() {
System.out.println("Meow meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog("Buddy", 3);
Animal myCat = new Cat("Whiskers", 2);
myDog.makeSound(); // 输出: Woof woof!
myCat.makeSound(); // 输出: Meow meow!
}
}
在这个例子中,Animal
类作为基类,定义了一个makeSound()
抽象方法,所有继承自它的子类(如Dog
和Cat
)都必须实现这个方法。这样,我们就能够通过一个统一的接口(即Animal
类)来处理不同类型的动物,体现了继承的优势。
第三章:多态的魔法 ------ 变身大师的技能
案例分析:图形绘制系统
在Java中,多态允许我们编写更加灵活和通用的代码,通过多态,同一段代码可以处理不同类型的对象,具体的行为由运行时对象的实际类型决定。
示例代码:
java
// 定义一个图形接口 Shape
public interface Shape {
double calculateArea();
}
// 实现 Shape 接口的 Circle 类
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
// 实现 Shape 接口的 Rectangle 类
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
System.out.println("Circle area: " + circle.calculateArea()); // 输出: Circle area: 78.53981633974483
System.out.println("Rectangle area: " + rectangle.calculateArea()); // 输出: Rectangle area: 24.0
}
}
在这个例子中,我们定义了一个Shape
接口,以及两个实现该接口的类Circle
和Rectangle
。通过多态,我们可以使用Shape
类型的引用指向任何实现了Shape
接口的对象,并调用其calculateArea()
方法。这样,我们就可以写出通用的代码,处理任意形状的图形,极大地提高了代码的灵活性和可扩展性。
设计模式与面向对象原则
深入理解封装、继承和多态之后,你将发现它们是许多高级编程概念和设计模式的基础。比如:
-
单一职责原则 :一个类应该只有一个引起它变化的原因,这正是封装思想的体现。例如,在
BankAccount
类中,我们通过将balance
设置为私有变量,并提供公共方法来操作它,确保了账户的职责清晰。 -
开放封闭原则 :对扩展开放,对修改关闭。继承和多态机制是实现这一原则的关键。例如,在
Animal
类的例子中,我们定义了一个抽象方法makeSound()
,所有的子类都必须实现这个方法。这样,当我们需要添加新的动物类型时,只需创建一个新的子类即可,无需修改现有代码。 -
工厂模式:这是一种常用的创建型设计模式,用于封装对象的创建过程。通过工厂方法,我们可以根据传入的参数动态地创建对象,而无需指定具体的类。结合继承和多态,工厂模式可以提供非常灵活的对象创建机制。
-
策略模式:这是一种行为型设计模式,允许在运行时选择算法或行为。通过定义一组算法接口,然后让不同的策略类实现这些接口,我们可以根据实际需求动态地切换策略,这充分体现了多态的灵活性。