【问题标题】:java calling method before supersuper之前的java调用方法
【发布时间】:2018-01-17 09:06:04
【问题描述】:

假设我有一个在它的构造函数中有 3 个参数的超类,并且我正在继承这个也有一个具有 3 个参数的构造函数的类,我想调用超类构造函数,但在我想做一些逻辑之前首先子类,我可以调用一个静态方法来接收这3个参数,但我必须只返回一个,所以这就是我想出的解决方案

public class someClass extends  SuperClass {
    public someClass(int a,int b,int c) {
         super(func(a,b,c),b,c);
    }
    public static int func(int a,int b,int c){
        //usage a b c
        return a;
    }
}

看起来有点难看,我想知道是否有更好的解决方案来自己使用参数,然后定期调用 super。请注意,我无法更改超类或子类的用法,因此无法更改工厂设计模式

【问题讨论】:

  • ...您知道构造函数不应该真正包含“逻辑”,对吧?所以,如果我理解正确的话:你想在一个甚至没有完全实例化的对象上运行业务逻辑?
  • 你的func方法总是返回a吗(这意味着超级调用总是super(a,b,c)?如果是这样的话,我认为没有理由在super(a,b,c)之前调用func .
  • 我想调用外部逻辑,比如打开一个文件,这与我实例化的对象本身并不完全相关
  • 我不完全确定我是否正确理解了你想要做什么,但是 Builder 模式呢?您可以在以这种方式调用构造函数之前执行您的逻辑。
  • @Turing85 绝对不是!请查看他们的help center。这是示例代码,在 Code Review 中是非常非法的。

标签: java constructor super


【解决方案1】:

要从构造函数中获取逻辑,您可以轻松地在子类中创建工厂方法:

public class SomeClass extends SuperClass {
    private SomeClass(int a, int b, int c) {
        super(a, b ,c);
    }

    public static SomeClass create(int a, int b, int c){
        // calculate a for constructor

        return new SomeClass(a, b, c);
    }
}

然后你可以按如下方式创建实例:

SomeClass someClass = SomeClass.create(1, 2, 3);

【讨论】:

  • 这个类的用户不会知道方法 create,我不能改变用户使用这个类的方式(他们将使用 SuperClass 的静态类型):即我不能强迫用户使用SomeClass someClass = SomeClass.create(1, 2, 3);
  • 如果他们使用SuperClass的静态类型,他们如何创建SomeClass的实例?你在使用反射吗?
  • 有一个类文件列表,一个方法接收并创建每个类文件的一个实例到一个超类列表中,我在这个列表中添加一个类文件。
  • 根据您的描述,代码有异味是因为设计有异味。如果你不能或不愿意改变设计,我想你只能忍受这种气味......
【解决方案2】:

在 Java 中,您不能在调用 super 之前执行另一条语句。您提到的技巧有效,但您不能重构代码以在调用super 之前的语句中调用func

根据我的经验,这样的问题通常暗示着一些设计问题。也许您可以通过重新考虑两个相关类的职责来解决根本问题。

【讨论】:

  • func 确实需要是 static。在调用super之前,您不能从构造函数中调用实例方法。
  • 这样的问题通常暗示着一些设计问题 +1
【解决方案3】:

您也可以使用构建器模式

public class SomeClass extends SuperClass {
    public static class Builder {
        private int a, b, c;
        public Builder withA(int a) { 
            this.a = a;
            return this;
        }
        public Builder withB(int b) { ... }
        public Builder withC(int c) { ... }
        public SomeClass build() {
            // logic goes here
            return new SomeClass(...)
        }
    }

    // hide this from public use, use Builder instead
    protected SomeClass(int a, int b, int, c) {
        super(a, b, c);
    }
}

SomeClass someClass = new SomeClass.Builder().
    withA(1).
    withB(2).
    withC(3).
    build();

【讨论】:

    猜你喜欢
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    相关资源
    最近更新 更多