Java里抽象类和普通类有什么区别_Java抽象设计说明

抽象类不能直接实例化,普通类可以;抽象类可含抽象方法且子类必须实现,否则自身须声明为abstract;抽象类可定义构造方法供子类调用。

抽象类不能直接 new,普通类可以

这是最直观、也是编译器最先报错的区别。当你写 new Shape()(假设 Shape 是抽象类),Java 直接拒绝编译,提示 "Cannot instantiate the type Shape"。而普通类如 RectangleString,调用 new Rectangle(2.0, 3.0) 完全合法。

  • 抽象类本质是“不完整的蓝图”,它缺方法体(比如 public abstract double calculateArea();),JVM 无法为其分配确定的内存布局
  • 普通类所有字段和方法都已定义完整,JVM 知道怎么构造对象、怎么调用方法
  • 即使抽象类里一个抽象方法都没有(比如 HttpServlet),只要加了 abstract 关键字,就不能 new

抽象类可以含 abstract 方法,普通类绝对不行

在普通类中写 public abstract void doSomething(); 会立刻触发编译错误:"Illegal combination of modifiers: 'public' and 'abstract'"。而抽象类中,抽象方法是核心设计手段。

  • 抽象方法只有声明,没有 {} 和实现逻辑,强制子类“补全”行为
  • 抽象方法默认是 publicprotected,不能是 private(子类看不见)、不能是 static(静态方法无法被重写)、也不能是 final(和重写冲突)
  • 注意:抽象类可以没有抽象方法;但反过来——只要类里有一个 abstract 方法,这个类就必须声明为 abstract

继承时子类必须实现抽象方法,否则自己也得标 abstract

这是最容易踩坑的一环:你以为继承了抽象类就“搞定”,结果编译报错 "The type X must implement the inherited abstract method Y"

  • 如果

    子类不是 abstract 类,它必须重写父类所有抽象方法,一个都不能少
  • 如果子类只实现了部分抽象方法,或一个都没实现,那它自己也得加上 abstract 修饰符,否则编译失败
  • 常见误操作:在子类里把抽象方法写成 private 或改了参数类型——这不算“实现”,只是重载,依然会报错

抽象类支持构造方法,但仅用于子类初始化时调用

很多人以为“不能 new 就不能有构造方法”,其实抽象类完全可以定义 Shape(String name) 这样的构造器,而且子类 super("circle") 必须显式调用它。

  • 抽象类的构造方法不会被直接执行,只在子类 new 实例时,由子类构造器链式调用
  • 可用于统一初始化共有的字段(比如所有图形都带 colorid),避免子类重复代码
  • 别在抽象类构造器里调用抽象方法——此时子类对象还没建好,会导致 NullPointerException 或未定义行为
抽象类的设计意图从来不是“多写几个关键字”,而是明确划出一条线:哪些能力必须由具体子类决定(抽象方法),哪些逻辑可以复用(普通方法),哪些状态属于全家共有(字段)。一旦混淆“能实例化”和“该不该实例化”,或者把抽象方法当成可选接口,就容易写出既难扩展又难测试的继承树。