抽象类不能直接实例化,但可作为方法参数或返回值类型,通过向上转型实现多态:形参强制接收具体子类对象,返回值承诺返回子类实例,依赖抽象类定义的契约统一调用接口。

Java 中抽象类不能直接实例化,但可以作为方法参数类型,起到类型约束和多态支持的作用。关键在于:方法声明用抽象类类型,实际传入的必须是它的具体子类对象。
抽象类作形参:只接受子类实例
当方法形参声明为抽象类类型时,编译器会强制要求传入该抽象类的非抽象子类对象。这是因为抽象类本身不可 new,只有子类完成所有抽象方法后才能被实例化。
- 形参写法:
void doSomething(Animal a)(Animal是 abstract class) - 合法调用:
doSomething(new Cat())、doSomething(new Dog()) - 非法调用:
doSomething(new Animal())→ 编译错误
抽象类作返回值:返回子类对象引用
方法返回类型声明为抽象类,表示它承诺返回一个该抽象类的实例——实际返回的是某个具体子类的对象,但调用方只需按抽象类型使用。
- 返回声明:
public Animal createAnimal() { return new Cat(); } - 调用方拿到的是
Animal类型引用,可安全调用其定义的公共方法(如eat()) - 底层对象仍是
Cat实例,具备运行时多态行为
为什么能这样设计?依赖多态与向上转型
Java 允许子类对象自动赋值给父类或抽象类类型的变量,这叫向上转型。抽象类在此充当“契约角色”:规定了哪些方法必须存在,却不关心具体实现。
- 调用方只依赖抽象类声明的 API,不耦合具体子类
- 新增子类(如
Bird extends Animal)无需修改原有方法签名,直接可传入 - 运行时根据实际对象类型决定执行哪个子类的重写方法
注意边界:不能绕过抽象约束
虽然可通过匿名内部类临时实现抽象类,但本质仍是创建了具体子类对象,不是“跳过抽象”。例如:
- 允许:
operateAnimal(new Animal() { public void eat() { System.out.println("吃虫"); } }); - 不允许:把普通类对象(如
String)强转成抽象类类型传入 —— 编译不通过 - 也不允许在重写抽象类方法时擅自缩小参数或返回类型(违反里氏替换原则)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











