在 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) 也涵盖了解决方案的一些细节,但仅限于 checking
和 name
作为条件的一部分。理想的情况是拥有一个适用于任何 String
字段的通用解决方案,而不仅仅是检查 name
。
您的代码有两部分需要抽象出来:
- 执行操作必须满足的条件
- 条件满足时执行的操作
这是你能做的:
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);
有几点需要注意:
- 我们制作
doSomething
final
因为这是我们不希望 sub类 更改的代码片段。我们将其设为 public
,以便客户端代码可以看到它。
- 我们制作
getCondtion
和 doSomethingOnCondition
protected
以便它们仅对 child 类 而不是客户端代码可见。我们让他们abstract
,这样child类就可以assemble条件和条件满足后要做的工作。
- 使用泛型,您可以扩展您的解决方案以适用于任何
data-type 而不仅仅是
String
。您所要做的就是介绍
type-parameter
在 Parent
我有以下 类:
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) 也涵盖了解决方案的一些细节,但仅限于 checking
和 name
作为条件的一部分。理想的情况是拥有一个适用于任何 String
字段的通用解决方案,而不仅仅是检查 name
。
您的代码有两部分需要抽象出来:
- 执行操作必须满足的条件
- 条件满足时执行的操作
这是你能做的:
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);
有几点需要注意:
- 我们制作
doSomething
final
因为这是我们不希望 sub类 更改的代码片段。我们将其设为public
,以便客户端代码可以看到它。 - 我们制作
getCondtion
和doSomethingOnCondition
protected
以便它们仅对 child 类 而不是客户端代码可见。我们让他们abstract
,这样child类就可以assemble条件和条件满足后要做的工作。 - 使用泛型,您可以扩展您的解决方案以适用于任何
data-type 而不仅仅是
String
。您所要做的就是介绍type-parameter
在Parent