Java 面向对象编程提供了继承、抽象类、接口、多态、内部类和异常处理等高级特性,这些特性使得代码更加灵活、可扩展和可维护。
继承 (Inheritance)
继承是面向对象编程的基石,允许子类继承父类的属性和方法:
// 父类
class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + "正在吃东西...");
}
public void sleep() {
System.out.println(name + "正在睡觉...");
}
// getter 和 setter 方法
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
// 子类继承父类
class Dog extends Animal {
private String breed; // 品种
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造方法
this.breed = breed;
}
// 子类特有的方法
public void bark() {
System.out.println(name + "汪汪叫...");
}
// 方法重写 (Override)
@Override
public void eat() {
System.out.println(name + "正在吃狗粮...");
}
// 子类特有的getter方法
public String getBreed() { return breed; }
public void setBreed(String breed) { this.breed = breed; }
}
// 另一个子类
class Cat extends Animal {
private String color;
public Cat(String name, int age, String color) {
super(name, age);
this.color = color;
}
public void meow() {
System.out.println(name + "喵喵叫...");
}
@Override
public void eat() {
System.out.println(name + "正在吃猫粮...");
}
public String getColor() { return color; }
public void setColor(String color) { this.color = color; }
}
// 测试类
public class InheritanceDemo {
public static void main(String[] args) {
Dog dog = new Dog("小黑", 3, "金毛");
Cat cat = new Cat("小花", 2, "白色");
// 调用继承的方法
dog.eat(); // 输出: 小黑正在吃狗粮...
dog.sleep(); // 输出: 小黑正在睡觉...
dog.bark(); // 输出: 小黑汪汪叫...
cat.eat(); // 输出: 小花正在吃猫粮...
cat.sleep(); // 输出: 小花正在睡觉...
cat.meow(); // 输出: 小花喵喵叫...
// 访问继承的属性
System.out.println("狗的名字: " + dog.getName());
System.out.println("狗的品种: " + dog.getBreed());
System.out.println("猫的颜色: " + cat.getColor());
}
}
抽象类 (Abstract Class)
抽象类不能实例化,用于定义子类必须实现的方法:
// 抽象类
abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 抽象方法 - 子类必须实现
public abstract double calculateArea();
public abstract double calculatePerimeter();
// 具体方法 - 子类可以继承使用
public void displayInfo() {
System.out.println("形状颜色: " + color);
System.out.println("面积: " + calculateArea());
System.out.println("周长: " + calculatePerimeter());
}
// getter 和 setter
public String getColor() { return color; }
public void setColor(String color) { this.color = color; }
}
// 具体子类 - 圆形
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
public double getRadius() { return radius; }
public void setRadius(double radius) { this.radius = radius; }
}
// 具体子类 - 矩形
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public double calculatePerimeter() {
return 2 * (width + height);
}
public double getWidth() { return width; }
public void setWidth(double width) { this.width = width; }
public double getHeight() { return height; }
public void setHeight(double height) { this.height = height; }
}
// 测试类
public class AbstractClassDemo {
public static void main(String[] args) {
// 不能实例化抽象类
// Shape shape = new Shape("红色"); // 编译错误
Circle circle = new Circle("蓝色", 5.0);
Rectangle rectangle = new Rectangle("绿色", 4.0, 6.0);
System.out.println("=== 圆形信息 ===");
circle.displayInfo();
System.out.println("\n=== 矩形信息 ===");
rectangle.displayInfo();
// 多态的使用
Shape[] shapes = {circle, rectangle};
System.out.println("\n=== 多态演示 ===");
for (Shape shape : shapes) {
shape.displayInfo();
System.out.println("------------");
}
}
}
接口 (Interface)
接口定义了一组方法规范,类可以实现多个接口:
// 接口定义
interface Flyable {
// 接口中的常量 (默认 public static final)
int MAX_SPEED = 1000;
// 抽象方法 (Java 8之前)
void fly();
// 默认方法 (Java 8+)
default void takeOff() {
System.out.println("准备起飞...");
}
// 静态方法 (Java 8+)
static void showMaxSpeed() {
System.out.println("最大飞行速度: " + MAX_SPEED + " km/h");
}
}
interface Swimmable {
void swim();
default void dive() {
System.out.println("潜入水中...");
}
}
interface Runnable {
void run();
default void walk() {
System.out.println("正在行走...");
}
}
// 类实现多个接口
class Duck implements Flyable, Swimmable, Runnable {
private String name;
public Duck(String name) {
this.name = name;
}
@Override
public void fly() {
System.out.println(name + "在低空飞行...");
}
@Override
public void swim() {
System.out.println(name + "在水中游泳...");
}
@Override
public void run() {
System.out.println(name + "在陆地上奔跑...");
}
// 重写默认方法
@Override
public void takeOff() {
System.out.println(name + "从水面起飞...");
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
// 另一个实现类
class Airplane implements Flyable {
private String model;
public Airplane(String model) {
this.model = model;
}
@Override
public void fly() {
System.out.println(model + "飞机在高空飞行...");
}
public String getModel() { return model; }
public void setModel(String model) { this.model = model; }
}
// 测试类
public class InterfaceDemo {
public static void main(String[] args) {
Duck duck = new Duck("唐老鸭");
Airplane airplane = new Airplane("波音747");
System.out.println("=== 鸭子行为 ===");
duck.takeOff();
duck.fly();
duck.swim();
duck.dive();
duck.run();
duck.walk();
System.out.println("\n=== 飞机行为 ===");
airplane.takeOff();
airplane.fly();
// 调用接口的静态方法
Flyable.showMaxSpeed();
// 多态的使用
Flyable[] flyables = {duck, airplane};
System.out.println("\n=== 多态飞行 ===");
for (Flyable flyable : flyables) {
flyable.takeOff();
flyable.fly();
System.out.println("------------");
}
}
}
多态 (Polymorphism)
多态允许使用父类引用指向子类对象,提高代码的灵活性:
// 父类
class Employee {
protected String name;
protected double baseSalary;
public Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
// 计算工资的方法 - 将在子类中被重写
public double calculateSalary() {
return baseSalary;
}
public void displayInfo() {
System.out.println("员工: " + name);
System.out.println("基本工资: " + baseSalary);
System.out.println("实发工资: " + calculateSalary());
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getBaseSalary() { return baseSalary; }
public void setBaseSalary(double baseSalary) { this.baseSalary = baseSalary; }
}
// 子类 - 经理
class Manager extends Employee {
private double bonus;
public Manager(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
public double calculateSalary() {
return baseSalary + bonus;
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("奖金: " + bonus);
}
public double getBonus() { return bonus; }
public void setBonus(double bonus) { this.bonus = bonus; }
}
// 子类 - 程序员
class Programmer extends Employee {
private int overtimeHours;
private double overtimeRate;
public Programmer(String name, double baseSalary, int overtimeHours, double overtimeRate) {
super(name, baseSalary);
this.overtimeHours = overtimeHours;
this.overtimeRate = overtimeRate;
}
@Override
public double calculateSalary() {
return baseSalary + (overtimeHours * overtimeRate);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("加班时长: " + overtimeHours);
System.out.println("加班费率: " + overtimeRate);
}
public int getOvertimeHours() { return overtimeHours; }
public void setOvertimeHours(int overtimeHours) { this.overtimeHours = overtimeHours; }
public double getOvertimeRate() { return overtimeRate; }
public void setOvertimeRate(double overtimeRate) { this.overtimeRate = overtimeRate; }
}
// 测试类
public class PolymorphismDemo {
public static void main(String[] args) {
// 创建不同类型的员工
Employee emp1 = new Manager("张三", 8000, 3000);
Employee emp2 = new Programmer("李四", 6000, 20, 50);
Employee emp3 = new Employee("王五", 5000);
// 多态数组
Employee[] employees = {emp1, emp2, emp3};
System.out.println("=== 员工工资信息 ===");
for (Employee emp : employees) {
emp.displayInfo();
System.out.println("------------");
}
// 计算总工资
double totalSalary = calculateTotalSalary(employees);
System.out.println("总工资支出: " + totalSalary);
// 类型检查和转换
System.out.println("\n=== 类型检查 ===");
for (Employee emp : employees) {
if (emp instanceof Manager) {
Manager manager = (Manager) emp;
System.out.println(manager.getName() + " 是经理,奖金: " + manager.getBonus());
} else if (emp instanceof Programmer) {
Programmer programmer = (Programmer) emp;
System.out.println(programmer.getName() + " 是程序员,加班时长: " + programmer.getOvertimeHours());
} else {
System.out.println(emp.getName() + " 是普通员工");
}
}
}
// 多态方法 - 可以处理所有Employee子类
public static double calculateTotalSalary(Employee[] employees) {
double total = 0;
for (Employee emp : employees) {
total += emp.calculateSalary();
}
return total;
}
}
内部类 (Inner Class)
内部类是在另一个类的内部定义的类,可以访问外部类的成员:
// 外部类
class OuterClass {
private String outerField = "外部类字段";
private static String staticOuterField = "静态外部类字段";
// 成员内部类
class MemberInnerClass {
private String innerField = "成员内部类字段";
public void display() {
System.out.println("访问外部类字段: " + outerField);
System.out.println("访问静态外部类字段: " + staticOuterField);
System.out.println("访问内部类字段: " + innerField);
// 调用外部类方法
outerMethod();
}
}
// 静态内部类
static class StaticInnerClass {
private String staticInnerField = "静态内部类字段";
public void display() {
// 只能访问外部类的静态成员
System.out.println("访问静态外部类字段: " + staticOuterField);
System.out.println("访问静态内部类字段: " + staticInnerField);
// 不能访问非静态成员
// System.out.println(outerField); // 编译错误
}
}
// 方法内部类 (局部内部类)
public void methodWithInnerClass() {
final String localVariable = "局部变量";
class LocalInnerClass {
public void display() {
System.out.println("访问外部类字段: " + outerField);
System.out.println("访问局部变量: " + localVariable);
}
}
LocalInnerClass localInner = new LocalInnerClass();
localInner.display();
}
// 匿名内部类
public void anonymousInnerClassDemo() {
// 使用匿名内部类实现接口
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类执行,访问外部字段: " + outerField);
}
};
new Thread(runnable).start();
}
private void outerMethod() {
System.out.println("外部类方法被调用");
}
// 测试内部类的方法
public void testInnerClasses() {
System.out.println("=== 成员内部类 ===");
MemberInnerClass memberInner = new MemberInnerClass();
memberInner.display();
System.out.println("\n=== 静态内部类 ===");
StaticInnerClass staticInner = new StaticInnerClass();
staticInner.display();
System.out.println("\n=== 方法内部类 ===");
methodWithInnerClass();
System.out.println("\n=== 匿名内部类 ===");
anonymousInnerClassDemo();
}
}
// 测试类
public class InnerClassDemo {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.testInnerClasses();
// 在其他类中创建内部类实例
System.out.println("\n=== 外部创建内部类 ===");
// 创建成员内部类实例
OuterClass.MemberInnerClass memberInner = outer.new MemberInnerClass();
memberInner.display();
// 创建静态内部类实例
OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
staticInner.display();
}
}
异常处理 (Exception Handling)
Java异常处理机制帮助程序优雅地处理运行时错误:
import java.util.InputMismatchException;
import java.util.Scanner;
// 自定义异常类
class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
super("资金不足,还差: " + amount + " 元");
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
class InvalidAmountException extends Exception {
public InvalidAmountException(String message) {
super(message);
}
}
// 银行账户类
class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// 存款方法
public void deposit(double amount) throws InvalidAmountException {
if (amount <= 0) {
throw new InvalidAmountException("存款金额必须大于0");
}
balance += amount;
System.out.println("存款成功,当前余额: " + balance);
}
// 取款方法
public void withdraw(double amount) throws InsufficientFundsException, InvalidAmountException {
if (amount <= 0) {
throw new InvalidAmountException("取款金额必须大于0");
}
if (amount > balance) {
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
balance -= amount;
System.out.println("取款成功,当前余额: " + balance);
}
// 转账方法
public void transfer(BankAccount target, double amount)
throws InsufficientFundsException, InvalidAmountException {
this.withdraw(amount); // 可能抛出异常
target.deposit(amount); // 可能抛出异常
System.out.println("转账成功!");
}
public String getAccountNumber() { return accountNumber; }
public double getBalance() { return balance; }
}
// 测试类
public class ExceptionHandlingDemo {
public static void main(String[] args) {
BankAccount account1 = new BankAccount("123456", 1000);
BankAccount account2 = new BankAccount("654321", 500);
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n=== 银行系统菜单 ===");
System.out.println("1. 存款");
System.out.println("2. 取款");
System.out.println("3. 转账");
System.out.println("4. 查询余额");
System.out.println("5. 退出");
System.out.print("请选择操作: ");
try {
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.print("请输入存款金额: ");
double depositAmount = scanner.nextDouble();
account1.deposit(depositAmount);
break;
case 2:
System.out.print("请输入取款金额: ");
double withdrawAmount = scanner.nextDouble();
account1.withdraw(withdrawAmount);
break;
case 3:
System.out.print("请输入转账金额: ");
double transferAmount = scanner.nextDouble();
account1.transfer(account2, transferAmount);
break;
case 4:
System.out.println("账户 " + account1.getAccountNumber() + " 余额: " + account1.getBalance());
System.out.println("账户 " + account2.getAccountNumber() + " 余额: " + account2.getBalance());
break;
case 5:
System.out.println("感谢使用,再见!");
scanner.close();
return;
default:
System.out.println("无效的选择!");
}
} catch (InputMismatchException e) {
System.out.println("输入格式错误,请输入数字!");
scanner.nextLine(); // 清除错误输入
} catch (InsufficientFundsException e) {
System.out.println("取款失败: " + e.getMessage());
System.out.println("还需要: " + e.getAmount() + " 元");
} catch (InvalidAmountException e) {
System.out.println("操作失败: " + e.getMessage());
} catch (Exception e) {
System.out.println("发生未知错误: " + e.getMessage());
e.printStackTrace();
}
}
}
// 演示 finally 块的使用
public static void fileOperationDemo() {
Scanner fileScanner = null;
try {
// 模拟文件操作
fileScanner = new Scanner(System.in);
System.out.print("请输入文件名: ");
String fileName = fileScanner.nextLine();
if (fileName.isEmpty()) {
throw new IllegalArgumentException("文件名不能为空");
}
System.out.println("正在处理文件: " + fileName);
// 模拟文件处理逻辑
} catch (IllegalArgumentException e) {
System.out.println("参数错误: " + e.getMessage());
} finally {
// 无论是否发生异常,都会执行 finally 块
if (fileScanner != null) {
fileScanner.close();
System.out.println("资源已释放");
}
}
}
// 演示 try-with-resources (Java 7+)
public static void tryWithResourcesDemo() {
// 自动资源管理,不需要显式关闭
try (Scanner autoScanner = new Scanner(System.in)) {
System.out.print("请输入数据: ");
String data = autoScanner.nextLine();
System.out.println("你输入的是: " + data);
} catch (Exception e) {
System.out.println("发生错误: " + e.getMessage());
}
// 资源会自动关闭
}
}
关键概念总结
- 继承:子类继承父类的属性和方法,实现代码复用
- 抽象类:包含抽象方法的类,不能实例化,用于定义规范
- 接口:定义方法规范,类可以实现多个接口,支持多重继承
- 多态:同一操作作用于不同对象,可以有不同的解释和执行结果
- 内部类:在类内部定义的类,可以更好地封装和组织代码
- 异常处理:使用 try-catch-finally 处理程序运行时的错误
最佳实践
- 优先使用组合而不是继承
- 接口用于定义行为,抽象类用于代码复用
- 合理使用多态提高代码的灵活性
- 内部类应该只在外部类中使用时才定义
- 异常处理要具体,不要捕获所有异常
- 自定义异常要提供有意义的错误信息
- 使用 try-with-resources 自动管理资源
注意:这些面向对象的高级特性是Java编程的核心,熟练掌握它们对于编写高质量、可维护的Java代码至关重要。
提示: 这是一个重要的概念,需要特别注意理解和掌握。
注意: 这是一个常见的错误点,请避免犯同样的错误。