Appearance
面向对象进阶
本章将深入讲解 Java 面向对象的高级特性,包括继承、多态、抽象类和接口。
继承
继承是面向对象的核心特性之一,允许子类继承父类的属性和方法。
继承的基本概念
text
┌─────────────────────────────────────────────────────────────────┐
│ 继承关系 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Animal(父类) │
│ / \ │
│ Dog(子类) Cat(子类) │
│ │
│ 子类继承父类的: │
│ - public 和 protected 成员 │
│ - 默认访问权限的成员(同一包中) │
│ │
│ 子类不继承: │
│ - private 成员 │
│ - 构造方法 │
└─────────────────────────────────────────────────────────────────┘继承的实现
java
// 父类:动物类
class Animal {
String name;
int age;
public Animal() {
System.out.println("Animal 无参构造");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Animal 有参构造");
}
public void eat() {
System.out.println(name + "正在吃东西");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 子类:狗类
class Dog extends Animal {
String breed; // 品种
public Dog() {
super(); // 调用父类无参构造(默认)
System.out.println("Dog 无参构造");
}
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类有参构造
this.breed = breed;
System.out.println("Dog 有参构造");
}
// 子类特有方法
public void bark() {
System.out.println(name + "正在汪汪叫");
}
// 重写父类方法
@Override
public void eat() {
System.out.println(name + "正在吃狗粮");
}
}
public class InheritanceDemo {
public static void main(String[] args) {
Dog dog = new Dog("旺财", 3, "金毛");
// 调用继承的方法
dog.sleep();
// 调用重写的方法
dog.eat();
// 调用子类特有方法
dog.bark();
System.out.println("\n狗的信息:");
System.out.println("名字:" + dog.name);
System.out.println("年龄:" + dog.age);
System.out.println("品种:" + dog.breed);
}
}方法重写
java
class Shape {
public void draw() {
System.out.println("绘制图形");
}
public double getArea() {
return 0;
}
}
class Circle extends Shape {
double radius;
public Circle(double radius) {
this.radius = radius;
}
// 重写父类方法
@Override
public void draw() {
System.out.println("绘制圆形");
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
double width;
double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制矩形");
}
@Override
public double getArea() {
return width * height;
}
}
public class OverrideDemo {
public static void main(String[] args) {
Shape shape1 = new Circle(5);
Shape shape2 = new Rectangle(4, 6);
shape1.draw(); // 绘制圆形
shape2.draw(); // 绘制矩形
System.out.println("圆面积:" + shape1.getArea());
System.out.println("矩形面积:" + shape2.getArea());
}
}super 关键字
java
class Parent {
String name = "父类";
public Parent() {
System.out.println("父类构造方法");
}
public void method() {
System.out.println("父类方法");
}
}
class Child extends Parent {
String name = "子类";
public Child() {
super(); // 调用父类构造方法(必须放在第一行)
System.out.println("子类构造方法");
}
public void show() {
System.out.println(name); // 子类的 name
System.out.println(super.name); // 父类的 name
}
@Override
public void method() {
super.method(); // 调用父类方法
System.out.println("子类方法");
}
}
public class SuperDemo {
public static void main(String[] args) {
Child child = new Child();
child.show();
child.method();
}
}多态
多态是指同一行为具有不同表现形式的能力。
多态的实现
java
// 父类
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
}
// 子类
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
}
class Cow extends Animal {
@Override
public void makeSound() {
System.out.println("哞哞哞");
}
}
public class PolymorphismDemo {
public static void main(String[] args) {
// 多态:父类引用指向子类对象
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Cow();
// 同一方法调用,不同表现
animal1.makeSound(); // 汪汪汪
animal2.makeSound(); // 喵喵喵
animal3.makeSound(); // 哞哞哞
// 多态数组
Animal[] animals = {new Dog(), new Cat(), new Cow()};
for (Animal animal : animals) {
animal.makeSound();
}
// 多态作为方法参数
System.out.println("\n方法参数多态:");
animalSound(new Dog());
animalSound(new Cat());
}
// 多态作为方法参数
public static void animalSound(Animal animal) {
animal.makeSound();
}
}类型转换
java
class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃骨头");
}
public void bark() {
System.out.println("汪汪叫");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void meow() {
System.out.println("喵喵叫");
}
}
public class TypeConversion {
public static void main(String[] args) {
// 向上转型(自动):子类 → 父类
Animal animal = new Dog(); // 向上转型
animal.eat(); // 调用 Dog 的 eat
// animal.bark(); // 编译错误:父类引用不能调用子类特有方法
// 向下转型(强制):父类 → 子类
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 向下转型
dog.bark(); // 现在可以调用子类特有方法
}
// instanceof 判断对象类型
Animal animal2 = new Cat();
System.out.println("animal2 是 Dog 吗?" + (animal2 instanceof Dog)); // false
System.out.println("animal2 是 Cat 吗?" + (animal2 instanceof Cat)); // true
System.out.println("animal2 是 Animal 吗?" + (animal2 instanceof Animal)); // true
// 类型转换异常
if (animal2 instanceof Dog) {
Dog dog = (Dog) animal2; // 不会执行
} else {
System.out.println("animal2 不是 Dog 类型");
}
// ClassCastException 示例
try {
Dog dog = (Dog) animal2; // ClassCastException
} catch (ClassCastException e) {
System.out.println("类型转换异常:" + e.getMessage());
}
}
}多态应用示例
java
// 抽象的支付方式
abstract class Payment {
protected double amount;
public Payment(double amount) {
this.amount = amount;
}
public abstract void pay();
}
// 支付宝支付
class Alipay extends Payment {
public Alipay(double amount) {
super(amount);
}
@Override
public void pay() {
System.out.println("使用支付宝支付:" + amount + "元");
}
}
// 微信支付
class WeChatPay extends Payment {
public WeChatPay(double amount) {
super(amount);
}
@Override
public void pay() {
System.out.println("使用微信支付:" + amount + "元");
}
}
// 银行卡支付
class BankCardPay extends Payment {
private String cardNumber;
public BankCardPay(double amount, String cardNumber) {
super(amount);
this.cardNumber = cardNumber;
}
@Override
public void pay() {
System.out.println("使用银行卡(" + cardNumber + ")支付:" + amount + "元");
}
}
public class PaymentDemo {
public static void main(String[] args) {
// 多态数组
Payment[] payments = {
new Alipay(100.0),
new WeChatPay(200.0),
new BankCardPay(300.0, "6222****1234")
};
// 统一处理支付
for (Payment payment : payments) {
payment.pay();
}
}
}抽象类
抽象类是不能被实例化的类,用于定义子类的通用模板。
抽象类定义
java
// 抽象类:图形
abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 抽象方法:没有方法体,子类必须实现
public abstract double getArea();
public abstract double getPerimeter();
// 具体方法:子类可以直接继承
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
// 显示信息
public void showInfo() {
System.out.println("颜色:" + color);
System.out.println("面积:" + getArea());
System.out.println("周长:" + getPerimeter());
}
}
// 具体子类:圆形
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public double getPerimeter() {
return 2 * Math.PI * 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 getArea() {
return width * height;
}
@Override
public double getPerimeter() {
return 2 * (width + height);
}
}
public class AbstractDemo {
public static void main(String[] args) {
// Shape shape = new Shape("红色"); // 编译错误:抽象类不能实例化
Shape circle = new Circle("红色", 5);
Shape rectangle = new Rectangle("蓝色", 4, 6);
circle.showInfo();
System.out.println();
rectangle.showInfo();
}
}抽象类特点
text
┌─────────────────────────────────────────────────────────────────┐
│ 抽象类特点 │
├─────────────────────────────────────────────────────────────────┤
│ 1. 使用 abstract 关键字修饰 │
│ 2. 不能被实例化 │
│ 3. 可以有抽象方法(没有方法体) │
│ 4. 可以有具体方法、构造方法、成员变量 │
│ 5. 子类必须实现所有抽象方法,否则也是抽象类 │
│ 6. 可以有 main 方法 │
└─────────────────────────────────────────────────────────────────┘接口
接口是一种完全抽象的类型,定义了一组方法的规范。
接口定义
java
// 接口:飞行能力
interface Flyable {
// 常量:默认 public static final
int MAX_HEIGHT = 10000;
// 抽象方法:默认 public abstract
void fly();
// 默认方法(Java 8+):可以有方法体
default void showMaxHeight() {
System.out.println("最大飞行高度:" + MAX_HEIGHT);
}
// 静态方法(Java 8+)
static void checkWeather() {
System.out.println("检查天气状况");
}
}
// 接口:游泳能力
interface Swimmable {
void swim();
}
// 实现类:鸭子(可以飞也可以游泳)
class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子在低空飞行");
}
@Override
public void swim() {
System.out.println("鸭子在水里游泳");
}
}
// 实现类:飞机(只能飞)
class Airplane implements Flyable {
@Override
public void fly() {
System.out.println("飞机在万米高空飞行");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly();
duck.swim();
duck.showMaxHeight(); // 调用默认方法
Flyable.checkWeather(); // 调用静态方法
System.out.println("最大高度:" + Flyable.MAX_HEIGHT); // 访问常量
// 多态
Flyable flyable1 = new Duck();
Flyable flyable2 = new Airplane();
flyable1.fly();
flyable2.fly();
}
}接口继承
java
// 基础接口
interface A {
void methodA();
}
interface B {
void methodB();
}
// 接口多继承
interface C extends A, B {
void methodC();
}
// 实现类
class ImplC implements C {
@Override
public void methodA() {
System.out.println("实现 methodA");
}
@Override
public void methodB() {
System.out.println("实现 methodB");
}
@Override
public void methodC() {
System.out.println("实现 methodC");
}
}
public class InterfaceInheritance {
public static void main(String[] args) {
C impl = new ImplC();
impl.methodA();
impl.methodB();
impl.methodC();
}
}接口与抽象类对比
text
┌─────────────────────────────────────────────────────────────────┐
│ 接口 vs 抽象类 │
├─────────────────────────────────────────────────────────────────┤
│ 特性 │ 接口 │ 抽象类 │
├─────────────────────────────────────────────────────────────────┤
│ 实例化 │ 不能 │ 不能 │
│ 构造方法 │ 没有 │ 可以有 │
│ 成员变量 │ 只能是常量 │ 可以有变量 │
│ 抽象方法 │ 可以 │ 可以 │
│ 具体方法 │ 默认方法(Java8)│ 可以 │
│ 多继承 │ 支持 │ 不支持 │
│ 设计理念 │ "能做什么" │ "是什么" │
└─────────────────────────────────────────────────────────────────┘final 关键字
final 关键字表示"最终的",不可改变的。
java
// final 类:不能被继承
final class FinalClass {
// final 变量:只能赋值一次(常量)
final int MAX_VALUE = 100;
// final 方法:不能被重写
public final void finalMethod() {
System.out.println("final 方法不能被重写");
}
// final 参数:方法内不能修改
public void method(final int param) {
// param = 10; // 编译错误
System.out.println(param);
}
}
// class SubClass extends FinalClass { } // 编译错误:不能继承 final 类
public class FinalDemo {
public static void main(String[] args) {
FinalClass fc = new FinalClass();
// fc.MAX_VALUE = 200; // 编译错误:不能修改 final 变量
// final 引用变量:引用不能变,但对象内容可以变
final int[] arr = {1, 2, 3};
arr[0] = 100; // 可以修改数组元素
// arr = new int[5]; // 编译错误:不能改变引用
}
}内部类
内部类是定义在另一个类内部的类。
成员内部类
java
class Outer {
private String outerField = "外部类字段";
private static String outerStaticField = "外部类静态字段";
// 成员内部类
class Inner {
private String innerField = "内部类字段";
public void show() {
System.out.println("访问外部类字段:" + outerField);
System.out.println("访问内部类字段:" + innerField);
}
}
public void createInner() {
Inner inner = new Inner();
inner.show();
}
}
public class InnerClassDemo {
public static void main(String[] args) {
// 创建成员内部类对象
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();
}
}静态内部类
java
class Outer {
private static String staticField = "静态字段";
private String instanceField = "实例字段";
// 静态内部类
static class StaticInner {
public void show() {
System.out.println("访问外部静态字段:" + staticField);
// System.out.println(instanceField); // 编译错误:不能访问实例字段
}
}
}
public class StaticInnerDemo {
public static void main(String[] args) {
// 创建静态内部类对象
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();
}
}局部内部类
java
class Outer {
public void method() {
final int localVar = 10; // 局部变量
// 局部内部类
class LocalInner {
public void show() {
System.out.println("局部变量:" + localVar);
}
}
LocalInner inner = new LocalInner();
inner.show();
}
}
public class LocalInnerDemo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}匿名内部类
java
interface Greeting {
void greet();
}
public class AnonymousInnerDemo {
public static void main(String[] args) {
// 匿名内部类:实现接口
Greeting greeting = new Greeting() {
@Override
public void greet() {
System.out.println("你好,匿名内部类!");
}
};
greeting.greet();
// 匿名内部类:作为方法参数
sayHello(new Greeting() {
@Override
public void greet() {
System.out.println("作为参数的匿名内部类");
}
});
// Lambda 表达式(Java 8+)简化
Greeting lambda = () -> System.out.println("Lambda 表达式");
lambda.greet();
}
public static void sayHello(Greeting greeting) {
greeting.greet();
}
}小结
本章我们学习了:
- 继承:子类继承父类的属性和方法,使用 extends 关键字
- 方法重写:子类重新定义父类的方法
- 多态:同一行为具有不同表现形式
- 抽象类:不能实例化,可以包含抽象方法
- 接口:定义方法规范,支持多实现
- final 关键字:表示不可改变
- 内部类:定义在类内部的类
下一章,我们将学习 异常处理,了解 Java 的异常处理机制。
