我发现了一些覆盖方法,它们不使用方法签名中的所有参数。
例如:
@Override
protected void setSomething(Object a, Object b, Object c) {
this.a = a
this.b = b;
// the parameter c is not used (ignored)
}
通常,父类不应该关心孩子们如何实现抽象方法。
但是在MHO中,方法的论点是有用的,当子类实现不需要参数时,这种情况非常罕见,当发生这种情况时,可能会出现问题。接口的设计或抽象类的设计。
一个功能的基础是:输入 - >输入过程 - >输出。
有时您需要计算这些输入,但如果您不在功能过程中使用其中一些输入,则这些输入不应作为您功能的输入。
你可以跳过这些输入的计算,调用一个使用所有输入的精确函数,这样就可以得到准确的函数。
唯一可以接受这种情况的情况是,当我们不想要父类的行为时,我们可以这样写:
@Override
protected void setSomething(Object a, Object b, Object c) {
//Nothing to do
}
或者
@Override
protected void setSomething(Object a, Object b, Object c) {
throw new UnsupportedOperationException(...);
}
索纳说:
未使用的参数具有误导性。无论传递给这样的价值 参数是,行为将是相同的。
我的问题是: 当我们覆盖方法时,我们应该使用方法签名中的所有参数吗?
当我说“使用所有参数'时,我试着说方法签名中的所有参数都在方法的正文(实现)中使用。
答案 0 :(得分:4)
当我们覆盖方法时,我们应该使用方法签名中的所有参数吗?
覆盖方法时,覆盖方法必须定义与超级方法相同的参数。
您没有义务使用实现中的所有参数 - 这取决于您希望通过此实现实现的目标,有时可能不需要所有参数。
但是,在方法实现中使用未使用的方法参数是设计不佳的标志。在定义方法(abstract
或已实现)时,您应该尝试回答“我为什么需要此参数?”和“这个参数总是会被使用? “。如果可能存在某些参数不会在实现中使用的情况,那么您可以定义一些重载方法。
举个例子。我们有这个方法
void someMethod(String first, String optionalParameter) { ... }
第二个参数是可选的(即可能需要或可能不是) - 您可以在不需要参数时传递null
或任何内容。在这种情况下,我会重载两个方法
void someMethod(String first) { ... }
void someMethod(String first, String second) { ... }
我还将确保在相应的实现中使用所有参数。
答案 1 :(得分:1)
你需要使用所有参数吗?不会。您经常会看到以下示例:
@Override
public void doFoo(String thingy) {
// no-op
}
或者
@Override
public void doFoo(String thingy) {
throw new UnsupportedOperationException(...);
}
但两者都是某种可疑设计的标志。例如,java.util.List
或甚至java.util.Iterable
都通过提供变异方法排除了不可变集合的可能性。不可变实现必须抛出UnsupportedOperationException
。
答案 2 :(得分:0)
如果覆盖方法,则必须使用所有参数。
但是你也可以重载一个方法 - 编写一个具有相同名称但不同参数的方法。因此,如果您不使用所有参数,则会超载,而不是覆盖。
class Accessor {
public void doSomething(String attr) {}
}
class Child extends Accessor {
// This is overriding
@Override
public void doSomething(String attr) {
// ...
}
// This is overloading
public void doSomething() {
// ...
}
}
答案 3 :(得分:0)
正如你所说:“我们应该” - 但我们不必这样做。有时,实现方法甚至会抛出RuntimeException
,例如Java Collections Framework的UnsupportedOperationException。