如果我们在可覆盖的方法中指定'super',这是否重要?

时间:2017-06-03 19:57:32

标签: java android

重写方法时是否指定关键字“super”是否重要?

如果是,在什么条件下它确实重要?

1.   
@Override
public void foo() {
super.foo();
}

2. 
@Override
public void foo() {
}

4 个答案:

答案 0 :(得分:3)

如果super在实施该方法方面有任何工作要做,那就很重要了。

通常,super确实有一些工作要做,否则该方法将是抽象的而不是可覆盖的。

如果您已撰写super,那么您就知道是否应该调用super。如果其他人写了super,您需要查看他们的文档。

如果您使用的是IntelliJ IDEA,则默认情况下,如果省略调用super,IntelliJ IDEA将发出警告。在设置 - >下编辑 - >检查 - > Java - >继承问题你会发现"方法不会调用超级方法"控制此警告的检查。如果您希望在特定方法而不是所有方法上发出此警告,那么您可以使用" Only报告,当supper方法注释时:"选项。我为此创建了以下注释:

package javax.annotation;

import java.lang.annotation.*;

/**
 * Overriding-Methods-Must-Invoke-Super annotation.
 * See JSR 305: Annotations for Software Defect Detection
 *              (https://jcp.org/en/jsr/detail?id=305)
 */
@Retention( RetentionPolicy.CLASS )
@Target( ElementType.METHOD )
public @interface OverridingMethodsMustInvokeSuper
{
}

这样,当我真的希望所有后代调用super时,我用@OverridingMethodsMustInvokeSuper注释super。

答案 1 :(得分:3)

这完全取决于你想要发生什么。如果父类(超级)具有您仍希望执行的功能,则需要调用super.foo()。这将是一个可能需要父类执行其功能的方法,然后子类在父类执行其操作后添加更多逻辑。

否则,如果要完全替换父类正在执行的操作,则不希望调用super.foo()。这将确保无论父类通过调用函数做什么都不会执行。这是一个例子:

public class Parent {
    public void printSomething() {
        System.out.println("I'm a Parent!");
    }
}

public class Child extends Parent {
    @Override
    public void printSomething() {
        super.printSomething();
        System.out.println("I'm a Child!");
    }
}

调用Child printSomething会导致:

I'm a Parent!
I'm a Child!

如果你没有调用super.printSomething(),你会看到:

I'm a Child!

答案 2 :(得分:2)

取决于方法。

如果你采用一个框架,它经常做"事情"在父方法中也是如此。如果您知道父方法什么都不做,那么它并不重要,但是为了将来的兼容性,总是将调用添加到super中是一个好主意。

唯一的例外是当你真的不想拥有父方法所做的事情时。在这种情况下,你别无选择。

事实上,如果你使用像Android或Spring这样的框架,你最终会因为这个原因而重写方法。

答案 3 :(得分:1)

  

如果我们指定关键字" super"是否重要?什么时候覆盖   方法

调用super.methodName()有一个含义:它调用当前实例的父类中实现的方法。
所以,是的,这很重要。

当我们从父类重写方法时,我们想要为这个子类定义一个特定的行为。这种特定的行为有两种风格:

  • 大部分时间,子类还需要继承父行为(添加父行为和当前类行为):在重写方法中,我们调用super.methodName()并执行特定行为点。

  • 但在某些特定情况下,子类需要定义一个特定的行为而不继承父类的行为:在覆盖的方法中,我们不会调用super.methodName()而我们这样做只有特定的行为