You need to enable JavaScript to run this app. 如何将抽象类子类作为方法参数,实现不同子类对象的统一初始化
优惠活动
大模型
产品
解决方案
定价
更多

如何将抽象类子类作为方法参数,实现不同子类对象的统一初始化

解决方案

原有代码无法运行的核心原因是Java语法限制:new关键字后必须跟实际类类型,你传入的typeOfThePieceWeWantToInitialise是抽象类的实例对象,不能直接用于实例化。以下是两种可落地的实现方案:

方案1:函数式接口工厂(推荐,类型安全无额外开销)

适合Java 8及以上版本,利用构造方法引用实现,编译期即可检查参数合法性,无反射相关的性能损耗和运行时风险。

  1. 首先自定义匹配棋子构造方法签名的函数式接口:
// 入参、返回值完全匹配所有棋子子类的构造方法规则
@FunctionalInterface
public interface PieceFactory<T extends AbstractPiece> {
    T create(Color color, Position position);
}
  1. 修改initPiece方法,接收工厂接口作为参数:
public void initPiece(Position position, Color color, PieceFactory<? extends AbstractPiece> pieceFactory) {
    AbstractPiece piece = pieceFactory.create(color, position);
    // 此处补充将棋子加入棋盘、注册管理等后续业务逻辑
}
  1. 调用时直接传入对应子类的构造方法引用即可:
// 初始化黑方国王
initPiece(new Position(0, 0), Color.BLACK, King::new);
// 初始化白方王后
initPiece(new Position(0, 4), Color.WHITE, Queen::new);
// 初始化白方车
initPiece(new Position(0, 0), Color.WHITE, Rook::new);

注意:所有棋子子类需要存在访问权限为public、入参顺序为(Color, Position)的构造方法。

方案2:反射实现(适合需要动态传递类类型的场景)

如果业务需要传入类对象作为参数,可以用反射实现,需要手动处理运行时异常:

public void initPiece(Position position, Color color, Class<? extends AbstractPiece> pieceClass) 
        throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    // 获取对应子类匹配参数的构造方法
    Constructor<? extends AbstractPiece> constructor = pieceClass.getConstructor(Color.class, Position.class);
    AbstractPiece piece = constructor.newInstance(color, position);
    // 此处补充后续业务逻辑
}

调用时传入对应子类的Class对象即可:

initPiece(new Position(0, 0), Color.BLACK, King.class);

内容的提问来源于stack exchange,提问作者La Légende

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 20:24:05