我有以下课程:
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");
}
// ...
}
}
你可以看到两个类中check input validity
个checkName
个方法的部分是相同的。我知道没有办法将这个联合部分移动到父级的抽象checkName
方法,但是在那里一种避免这种重复的方法?
答案 0 :(得分:2)
你可以切换一下,以便checkName()
类中的Parent
函数是具体的,让它进行输入有效性检查,然后调用你的子类实现其余的一些抽象方法处理。
答案 1 :(得分:2)
以常规方式进行。在抽象类中创建真正的方法“检查输入有效性”,并在真实类的任何方法中使用它。 这是常规方式,它经常用于重构。
对所有类都有一个静态变量没有任何意义。 我认为,这就是你需要的:
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;
}
}
答案 2 :(得分:2)
David's回答涵盖解决方案的关键,但不包括解决方案的复杂性。其他答案(例如来自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
,因为这是我们不希望子类发生变化的代码段。我们将其设为public
,以便客户端代码可以看到它。getCondtion
和doSomethingOnCondition
protected
,以便它们仅对子类可见,而不是客户端代码。我们将它们设为abstract
,以便子类可以在条件满足后组合条件和要完成的工作。 String
。你所要做的就是介绍
type-parameter
Parent
醇>
答案 3 :(得分:1)
是。在父级上添加:
protected void checkNameEquality(String str) {
//check input validity:
if (!getNameForClass().equals(str)) {
throw new IllegalArgumentException("some thing");
}
}
和每个孩子的电话
checkNameEquality(str);
要访问静态名称,您需要添加另一个抽象方法来获取该类的名称。
abstract String getnameForClass();
并在每个孩子中实施。
没有办法强制实现者进行检查,但你只需要编写一次代码。
答案 4 :(得分:0)
使用通用实现在抽象类中创建一个方法,并从那里调用自定义(重写)实现:
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。