Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写时何时不调用super()方法?_Java_Android_Overriding - Fatal编程技术网

Java 重写时何时不调用super()方法?

Java 重写时何时不调用super()方法?,java,android,overriding,Java,Android,Overriding,当我创建自己的Android自定义类时,我扩展了它的本机类。然后,当我想重写基本方法时,我总是调用super()方法,就像我总是在onCreate,onStop中那样 我想就是这样,因为从一开始Android团队就建议我们在每个方法覆盖上总是调用super 但是,在许多书中我可以看到,比我更有经验的开发人员经常忽略调用super,我真的怀疑他们这样做是因为缺乏知识。例如,看看这个基本解析器类,其中startElement中省略了super,字符和endElement: public class

当我创建自己的Android自定义类时,我扩展了它的本机类。然后,当我想重写基本方法时,我总是调用
super()
方法,就像我总是在
onCreate
onStop
中那样

我想就是这样,因为从一开始Android团队就建议我们在每个方法覆盖上总是调用
super

但是,在许多书中我可以看到,比我更有经验的开发人员经常忽略调用
super
,我真的怀疑他们这样做是因为缺乏知识。例如,看看这个基本解析器类,其中
startElement
中省略了
super
字符
endElement

public class SAXParser extends DefaultHandler{
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        //do something
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }else () {
            //do something
        }
    }
}
如果您试图通过Eclipse或任何其他IDE创建任何覆盖方法,
super
将始终作为自动化过程的一部分创建

这只是一个简单的例子。书籍中充满了类似的代码

他们如何知道您何时必须调用super,何时可以省略调用

注意:不要拘泥于这个具体的例子。这只是从许多例子中随机选取的一个例子


(这听起来像是一个初学者的问题,但我真的很困惑。)

通过调用
super
方法,您不是在重写方法的行为,而是在扩展它

调用
super
将执行您要扩展的类为该方法定义的任何逻辑。考虑到在方法重写中调用
super
的实现的时刻可能很重要。例如:

public class A { 
    public void save() { 
         // Perform save logic
    }
}

public class B extends A {
    private Object b;
    @Override
    public void save() { 
        super.save(); // Performs the save logic for A
        save(b); // Perform additional save logic
    }
}
调用
B.save()
将按此特定顺序执行
A
B
save()
逻辑。如果您没有在
B.save()
内部调用
super.save()
,则不会调用
A.save()
。如果在
save(b)
之后调用
super.save()
A.save()
将在
b.save()
之后有效执行

如果您想覆盖
super
的行为(即完全忽略它的实现并自己提供),您不应该调用
super

在您提供的
SAXParser
示例中,这些方法的
DefaultHandler
的值为空,因此子类可以重写它们并为这些方法提供行为。文中还指出了这一点

public void startElement (String uri, String localName,
    String qName, Attributes attributes) throws SAXException {
    // no op
}

关于IDE生成的代码中的
super()。
IDE
只是为您写下它,但是如果您删除它,它也会被调用。还请注意,在实现构造函数时,
super()
或其任何带有参数的变体(即
super(x,y,z)
)只能在方法的最开始调用。

好的Xavi给出了更好的答案。。但您可能知道在重写方法中调用时,
super()
会做什么。。。它显示了你对默认行为做了什么

e、 g:

重写时视图类中的方法。。在说super.onDraw()之前先画一些东西。视图完全绘制后,它就会出现。。所以在这里调用
super
是必要的,因为android有一些非常重要的事情要做(比如onCreate())

但同时

onLongClick()

当您覆盖此选项时,您不想调用super,因为它会显示一个对话框,其中包含EditText或任何其他类似视图的选项列表。。这是基本区别。。有时你可以选择离开。。但是对于其他方法,如
onCreate(),onStop()
你应该让操作系统来处理它。

我没有弄清楚你的问题,但是如果你问为什么不调用
super
方法:

调用
super
方法有一个原因:如果父类中没有零参数构造函数,则不可能为其生成子类,因此您需要在父类中保留一个无参数构造函数,或者需要使用
参数定义
super()
调用语句(您在super类中使用了多少参数构造函数)
位于子类构造函数的顶部


我希望这有帮助。如果没有,请告诉我。

您应该在头脑中做的测试是:

“我想让这个方法的所有功能都为我完成,然后再做些什么吗?”如果是,那么你想调用
super()
,然后完成你的方法。这对于像
onDraw()
这样的“重要”方法来说是正确的,它在后台处理很多事情

如果您只需要一些功能(就像您将覆盖的大多数方法一样),那么您可能不想调用
super()

他们怎么知道你什么时候必须叫super,什么时候可以不叫super

通常,如果一个特殊的API方法对底层框架上下文生命周期具有关键意义,它将始终在API文档中明确说明和突出显示,如。此外,如果API遵循稳健的设计,它应该在项目编译时抛出一些异常以提醒消费者开发人员,并确保它我不会在运行时生成错误

如果API文档中没有明确说明这一点,那么消费者开发人员可以很安全地假设API方法在重写时不是必须调用的。消费者开发人员可以决定是使用默认行为(调用
super
方法)还是完全重写它

如果条件允许(我喜欢露天场地)
onLongClick()
public class ConstraintArrayList<T> extends ArrayList<T> {
  ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
  @Override
  public boolean add(T element) {
    if (cons.accept(element))
      return super.add(element);
    return false;
  }
}