在 sub-类 中重用条件语句。

Reuse conditional statements in sub-classes.

我有以下 类:

public abstract class Parent {

    public abstract boolean checkName(String str);
}


public class Child1 extends Parent {

    public static final String NAME = "CHILD1";

    @Override
    public boolean checkName(String str) {
        //check input validity:
        if (!NAME.equals(str)) {
            throw new IllegalArgumentException("some thing");
        }
        //...
    }
}


public class Child2 extends Parent {

    public static final String NAME = "CHILD2";

    @Override
    public boolean checkName(String str) {
        //check input validity:
        if (!NAME.equals(str)) {
            throw new IllegalArgumentException("some thing");
        }
        // ...
    }

}

你可以在两个 类 中看到 checkName 方法的 check input validity 部分 same.I 知道没有办法将这个联合部分移动到抽象 checkName 父方法,但是有没有办法避免这种重复?

你可以换个方式,让 checkName() 函数在 Parent class 中具体化,让它进行输入有效性检查,然后调用你的 child classes 执行剩下的处理。

是的。在 parent 添加:

protected void checkNameEquality(String str) {
          //check input validity:
    if (!getNameForClass().equals(str)) {
        throw new IllegalArgumentException("some thing");
    }

}

并且每次 child 调用

checkNameEquality(str);

要访问静态名称,您需要添加另一个抽象方法来获取该名称的名称 class。

abstract String getnameForClass();

并在每个 child 中实现它。

无法强制实施者进行检查,但您只需编写一次代码。

按常规方式进行。在抽象 class 中创建真实方法 "check input validity" 并在真实 classes 的任何方法中使用它。 这是常规方式,经常用于重构。

同时为所有 classes 使用一个静态变量是没有意义的。 这是我认为您需要的:

public abstract class Parent {

    public String NAME;

    public abstract boolean checkName(String str);

    public void checkInputValidity(String str) {
        if (!NAME.equals(str)) {
            throw new IllegalArgumentException("some thing");
        }
    }
}

class Child1 extends Parent {
    public Child1() {
        NAME = "CHILD1";
    }

    @Override
    public boolean checkName(String str) {
        checkInputValidity(str);
        // ...
        return true;
    }
}

class Child2 extends Parent {

    public Child2() {
        NAME = "CHILD2";
    }

    @Override
    public boolean checkName(String str) {
        // check input validity:
        checkInputValidity(str);
        // ...
        return true;
    }

}

在您的摘要 class 中使用通用实现创建一个方法,并从那里调用自定义(覆盖)实现:

public abstract class Parent {
    public final boolean checkName(String str) {
        if (!getName().equals(str)) {
            throw new IllegalArgumentException("some thing");
        }

        return _checkName(str);
    }

    public abstract boolean _checkName(String str);

    public abstract String getName();
}


public class Child1 extends Parent {

    public static final String NAME = "CHILD1";

    @Override
    public boolean _checkName(String str) {
        //...
    }

    public String getName() {
        return NAME;
    }
}


public class Child2 extends Parent {

    public static final String NAME = "CHILD2";

    @Override
    public boolean _checkName(String str) {
        // ...
    }

    public String getName() {
        return NAME;
    }

}

或者,您也可以从子方法中调用父项的 checkName。

David's answer covers the crux of the solution but does not cover intricacies of the solution. The other answers (such as the one from Alex) 也涵盖了解决方案的一些细节,但仅限于 checkingname 作为条件的一部分。理想的情况是拥有一个适用于任何 String 字段的通用解决方案,而不仅仅是检查 name

您的代码有两部分需要抽象出来:

  1. 执行操作必须满足的条件
  2. 条件满足时执行的操作

这是你能做的:

public abstract class Parent {

   public final void doSomething(String str) {
        if(getCondition(str)) {
            doSomethingOnCondition(str);
        } else {
            throw new IllegalArgumentException("some thing");
        }
    }

    protected abstract boolean getCondition(String str);

    protected abstract void doSomethingOnCondition(String str);


}


class Child1 extends Parent {

    public static final String NAME = "CHILD1";

    @Override
    protected void doSomethingOnCondition(String str) {
        System.out.println("doing something with "+str);
    }

    @Override
    protected boolean getCondition(String str) {
        return NAME.equals(str);
    }
}

然后客户端代码可以简单地调用 doSomething 方法,如下所示:

parent.doSomething(str);

有几点需要注意:

  1. 我们制作 doSomething final 因为这是我们不希望 sub类 更改的代码片段。我们将其设为 public,以便客户端代码可以看到它。
  2. 我们制作 getCondtiondoSomethingOnCondition protected 以便它们仅对 child 类 而不是客户端代码可见。我们让他们abstract,这样child类就可以assemble条件和条件满足后要做的工作。
  3. 使用泛型,您可以扩展您的解决方案以适用于任何 data-type 而不仅仅是 String。您所要做的就是介绍 type-parameterParent