一、多态
1.1多态的概念
多态是面向对象的三大特性之一,核心是 **"一个接口,多种实现"**。具体表现为:父类 / 接口的引用可以指向子类 / 实现类的对象,调用方法时会执行实际对象的重写方法。
1.2多态的前提:
- 存在继承 / 实现关系
- 方法重写(@Override)
- 父类 / 接口引用指向子类 / 实现类对象
1.3多态的实现方式
方法重写(Override)
子类继承父类并重写父类方法,通过父类引用调用子类对象时,实际执行的是子类的方法。
// 1. 父类:只定义一个通用方法
class Animal {
void shout() { // 通用行为:叫
System.out.println("动物叫");
}
}
// 2. 子类1:狗(重写父类的叫方法)
class Dog extends Animal {
@Override
void shout() {
System.out.println("汪汪汪");
}
}
// 3. 子类2:猫(重写父类的叫方法)
class Cat extends Animal {
@Override
void shout() {
System.out.println("喵喵喵");
}
}
// 测试:多态的核心体现
public class SimplePolymorphism {
public static void main(String[] args) {
// 核心:父类引用 指向 子类对象
Animal a1 = new Dog(); // 狗装到Animal类型的“盒子”里
Animal a2 = new Cat(); // 猫装到Animal类型的“盒子”里
// 调用同一个方法,执行不同逻辑(多态)
a1.shout(); // 输出:汪汪汪
a2.shout(); // 输出:喵喵喵
}
}
代码解释:
1.4向上和向下转型
- 向上转型:把子类对象 “装” 到父类类型的变量里(自动完成,不用手动操作),这是多态的基础;
- 向下转型:把已经向上转型的父类变量,“还原” 回子类类型(必须手动强转,且有风险)
// 父类
class Animal {
void shout() {
System.out.println("动物叫");
}
}
// 子类
class Dog extends Animal {
@Override
void shout() {
System.out.println("汪汪汪");
}
// 子类独有方法
void wagTail() {
System.out.println("摇尾巴");
}
}
public class CastTest {
public static void main(String[] args) {
// 向上转型:子类对象 → 父类引用(自动完成,不用写额外代码)
Animal a = new Dog();
// 能调用父类定义的方法(执行子类重写的逻辑)
a.shout(); // 输出:汪汪汪
// 不能调用子类独有的方法(父类引用“看不到”子类独有方法)
// a.wagTail(); // 编译报错!
}
}
向上转型只能引用父类有的方法 如果没有,编译则会报错
多态就是基于向上转型实现的。
public class CastTest {
public static void main(String[] args) {
// 第一步:先向上转型
Animal a = new Dog();
// 第二步:向下转型(强制转换,必须加 (子类类型))
Dog d = (Dog) a;
// 转型后:既能调用重写的方法,也能调用子类独有方法
d.shout(); // 输出:汪汪汪
d.wagTail(); // 输出:摇尾巴
// ❌ 错误示范:父类对象不能转成子类(会抛运行时异常)
// Animal a2 = new Animal();
// Dog d2 = (Dog) a2; // 运行时抛出 ClassCastException
}
}
- 必须手动强转:要写 (Dog) a,告诉编译器 “我确认这个父类引用指向的是 Dog 对象”;
- 前提条件:只有当父类引用实际指向的是该子类对象时,向下转型才安全(比如 a 实际是 Dog,才能转成 Dog);
二、接口
2.1接口的定义
接口(Interface)是纯抽象的 “行为契约 / 规范” —— 只规定 “要做什么”(定义方法名),不规定 “怎么做”(无方法体),由实现类(implements)去完成具体逻辑。
- 类比:就像 “遥控器接口”,只定义 “开机、换台” 按钮,电视、空调各自实现自己的开机 / 换台逻辑。
- 核心价值:统一行为标准、解耦代码、弥补 Java 单继承的不足。
2.2接口的实现
接口使用 interface 关键字声明,默认所有方法为 public abstract(隐式修饰符),属性为 public static final。
interface MyInterface {
void method1(); // 隐式为 public abstract
String CONSTANT = "VALUE"; // 隐式为 public static final
}
类通过 implements 关键字实现接口,必须重写接口中所有抽象方法(除非是抽象类)
class MyClass implements MyInterface {
@Override
public void method1() {
System.out.println("Implemented method");
}
}
2.2.2多接口实现
一个类可同时实现多个接口,需重写所有接口的抽象方法。
interface InterfaceA { void methodA(); }
interface InterfaceB { void methodB(); }
class MyClass implements InterfaceA, InterfaceB {
@Override
public void methodA() { /* 实现 */ }
@Override
public void methodB() { /* 实现 */ }
}
2.2.3接口继承
接口可通过 extends 继承其他接口,支持多继承。子接口会合并父接口的方法。
interface ParentA { void methodA(); }
interface ParentB { void methodB(); }
interface Child extends ParentA, ParentB { void methodC(); }
class MyClass implements Child {
@Override
public void methodA() { /* 实现 */ }
@Override
public void methodB() { /* 实现 */ }
@Override
public void methodC() { /* 实现 */ }
}
2.3接口+类基本用法
// 1. 定义接口:只规定行为,不实现
interface Runable {
// 抽象方法:只定义“跑”,无逻辑
void run();
// 默认方法:有通用逻辑,可选重写
default void warmUp() {
System.out.println("热身:活动关节");
}
// 静态方法:接口专属,只能通过接口名调用
static void rule() {
System.out.println("跑步规则:不要违规");
}
// 常量:默认public static final
int SPEED_LIMIT = 10; // 限速10
}
// 2. 实现类1:学生跑步(实现接口)
class Student implements Runable {
@Override
public void run() { // 必须实现抽象方法
System.out.println("学生慢跑,速度≤" + SPEED_LIMIT);
}
// 可选重写默认方法
@Override
public void warmUp() {
System.out.println("学生热身:拉伸腿");
}
}
// 3. 实现类2:运动员跑步(实现接口)
class Athlete implements Runable {
@Override
public void run() {
System.out.println("运动员冲刺,速度≤" + SPEED_LIMIT);
}
// 不重写默认方法,直接用接口的warmUp
}
// 测试
public class InterfaceDemo {
public static void main(String[] args) {
// 接口引用指向实现类(多态)
Runable s = new Student();
Runable a = new Athlete();
s.run(); // 输出:学生慢跑,速度≤10
s.warmUp(); // 输出:学生热身:拉伸腿
a.run(); // 输出:运动员冲刺,速度≤10
a.warmUp(); // 输出:热身:活动关节
Runable.rule(); // 静态方法:接口名.方法名调用
}
}
网硕互联帮助中心





评论前必须登录!
注册