父类的方法返回子类的对象问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
echooo0
V2EX    程序员

父类的方法返回子类的对象问题

  •  
  •   echooo0 2022-08-18 12:07:41 +08:00 2113 次点击
    这是一个创建于 1155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    TradeResult 类继承 FrontResultBuilder 泛型类,在 FrontResultBuilder 返回子类的对象。

    现在想把子类的 static build 方法也移到 FrontResultBuilder 泛型类中,提示 cannot be referenced from a static context 错误,怎么破。。。。

    public abstract class FrontResultBuilder<T extends FrontResultBuilder<T>> { private String code; private String msg; abstract T build(); @SuppressWarnings( "unchecked" ) public T code(String code) { this.code = code; return (T)this; } } public class TradeResult extends FrontResultBuilder<TradeResult> { private Date createTime; public static TradeResult build() { return new TradeResult(); } } 
    12 条回复    2022-08-19 14:33:05 +08:00
    nothingistrue
        1
    nothingistrue  
       2022-08-18 12:39:30 +08:00
    你的工厂方法从底子上就是有问题的,没法破。工厂方法是主类的辅助类,可以是主类的内部类,但绝对不能跟主类有继承关系。

    继承关系上也有问题:构造方法和静态方法都是不能继承 /覆盖的。
    echooo0
        2
    echooo0  
    OP
       2022-08-18 12:43:45 +08:00
    @nothingistrue #1 不是为了继承覆盖,build 方法要做成 static 的,看起来泛型类里面不支持 static 方法,只能在子类里面做了。。。。
    Achieve7
        3
    Achieve7  
       2022-08-18 14:04:37 +08:00
    静态和构造方法是没法继承的, 做个 adapter 吧
    ccppgo
        4
    ccppgo  
       2022-08-18 15:38:13 +08:00
    FrontResultBuilder 写一个 buid 方法,不需要抽象, 然后把 Class 作为参数传进来, 用反射新建对象类似:

    ```
    public <T extends ParentClass> T paramInit(Class<T> clazz) {
    T param = null;
    param = clazz.newInstance();
    return param;
    }
    ```
    echooo0
        5
    echooo0  
    OP
       2022-08-18 16:53:07 +08:00
    @ccppgo #4 方法看上去不美观哈哈。。。用静态 build 方法就是想简洁一点。。。。。
    nothingistrue
        6
    nothingistrue  
       2022-08-18 17:28:57 +08:00
    private Class<T> templateClz;

    构造器上中
    templateClz= (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

    然后 public T code(String code) 这个方法就能正常用了。

    有限制条件,就是子类必须像你写的那样继承,即必须继承 BaseClass<SomeClass>,且这个 SomeClass 只能声明一次,后面再继承的类,T 是固定成 SomeClass 的,不能换。

    另外这个实际上解决的是,抽象父类中怎么获取子类的泛型的问题,这里正常的用法应该是 public abstract class FrontResultBuilder<T> , T 跟 FrontResultBuilder 没有继承关系。

    这种方法是用了泛型的黑科技,来自于 Hibernate ,现在已经基本不用了,用注解会更方便。
    ccppgo
        7
    ccppgo  
       2022-08-18 18:51:13 +08:00
    @echooo0 你这种静态 build 看你的代码还要每个继承的类写一遍。。。。那继承还有什么意义
    anonymous256
        8
    anonymous256  
       2022-08-18 19:44:36 +08:00   2
    没学过 java ,不过你的设计肯定是有问题的。
    基类就不应该调用派生类的任何东西,不管技术上能不能实现,你都不应该这么做。
    这是一个道德性原则。
    sutra
        9
    sutra  
       2022-08-18 19:53:50 +08:00
    static 跟父子没关系。
    echooo0
        10
    echooo0  
    OP
       2022-08-18 21:03:27 +08:00
    @ccppgo #7 贴出来的代码思路没理清楚。。。。v 站也没修改的按钮。。。
    sky857412
        11
    sky857412  
       2022-08-19 12:11:07 +08:00
    你中间需要一个工厂类,static 调不了用非 static 方法,abstract 也无法修饰 static 方法,设计的有问题
    echooo0
        12
    echooo0  
    OP
      &bsp;2022-08-19 14:33:05 +08:00
    @sky857412 #11 大概的的设计思路是想在父类中,有个 build 方法来返回对应的子类对象,这就需要用到泛型,

    然后为了写起来简洁美观,这个 build 方法想设计成 static 的,但是泛型里面又没法有 static 方法,所以卡在这里。。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5376 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 06:58 PVG 14:58 LAX 23:58 JFK 02:58
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86