Java - 扩展类并重用其方法?

11
public class BaseClass {
   public void start() {
      // do something
   }
}

public class ClassA extends BaseClass {

}

ClassA c = new ClassA();
c.start();

在下面的代码中,我想使用在父类中定义的start()方法。我看到很多其他开发人员的代码中他们覆盖了父类中的这个方法,然后再调用super。这样做是否有原因?

public class ClassA extends BaseClass {
   @Override
   public void start() {
      super.start();
   }
}

1
@Jeanne Boyarsky,说得太对了!这是每个开发者的偏好问题,通常你的文档应该足够好,不需要这样做,但更清晰总比不清晰好。 - bdparrish
5个回答

11

清晰度?一些开发人员认为在子类中显示方法更清晰。我不同意。这是冗余信息。

至少从Java 5开始,您可以添加 @Override,这样编译器会告诉您签名是否更改/消失。

除了构造函数。对于构造函数,您确实必须创建具有相同签名并向上委托的自己的构造函数。在这种情况下,省略不等价。


2
+1 这是多余和令人困惑的。如果您看到该方法已被覆盖(即使您无法看到源代码,IDE也会向您显示),您会认为它除了继承的默认值之外还做了其他事情。此外,如果您覆盖该方法,则应为其编写Javadoc。 - Thilo
1
@Thilo: 我个人认为这并不更清晰,也不在我的团队中实践。争论的是,对于新手来说,不习惯查看超类。 (三元运算符也有同样的争论。)我不喜欢过度迁就非 Java 开发人员的东西。应该学习自己所工作语言的规则和习惯用法。 - Jeanne Boyarsky

10

重写一个方法,做一些特殊的事情,然后调用super.method()被称为装饰一个方法 - 你正在添加行为。在这里阅读更多信息:装饰器模式

如果不调用super的方法而进行重写,则简单地称为重写一个方法 - 改变行为。


6
public class ClassA extends BaseClass {
  @Override
  public void start() {
     super.start();
  }
}

不覆盖基类方法时,public class ClassA extends BaseClass {}的功能与基类相同。

因此,除非您有额外的功能要添加(在这种情况下,您调用超类的方法,然后添加您的额外逻辑),或者要做一些不同的事情(您不调用超类的方法,而只是定义一些不同的逻辑),否则最好不要覆盖超类的方法(并调用超类的方法),因为这是没有意义的。


1

有时候我会这样做(在开发过程中临时这样做),当我想在那里设置断点时。


@javaguy:那么它也会在超类实例中间断。 - Thilo

0
继承的主要原因是泛化子类中共有的函数或操作。只有需要为特定的子类自定义操作时才有必要重写。
但有一个地方需要进行覆盖,例如你在超类中重载了默认构造函数,则在子类中需要在子类构造函数的第一行中提及调用超类重载构造函数(即在子类创建前必须先创建超类对象)。
例如:
class BaseClass{
Baseclass(arg1){
}
}
class A extends BaseClass{
A(){
super(arg1);
}
}
在其他地方这只会增加代码的冗余,完全没有必要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接