问题
当我创建自己的Android自定义类时,Iextend
its是本机类。然后,当我想覆盖基本方法时,我总是调用super()
方法,就像我总是在onCreate
,onStop
等。
而且我认为就是这样,从一开始Android团队建议我们在每个方法覆盖时总是调用super
。
但是,在中,很多书我都可以看到,比我更有经验的开发人员经常省略调用super
而且我真的怀疑他们这样做是因为缺乏知识。例如,看看这个basicSAXparser类,其中super
在startElement
,characters
和2889581799中省略:
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
以及什么时候可以省略它?
PS。不要绑定到这个特定的例子。这只是从许多例子中随机挑选的一个例子。
(这听起来像是一个初学者的问题,但我真的很困惑。)
#1 热门回答(133 赞)
通过调用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()
逻辑。如果你没有打电话super.save()
insideB.save()
,A.save()
将无法召唤。如果你之后打电话super.save()
后save(b)
,A.save()
将会有效地执行B.save()
。
如果你想要覆盖super
的行为(也就是说,完全忽略它的实现并自己提供),你不应该调用super
。
在你提供的SAXParser
示例中,这些方法的implementations,DefaultHandler
只是空的,因此子类可以覆盖它们并为这些方法提供行为。在这种方法的javadoc中也指出了这一点。
public void startElement (String uri, String localName,
String qName, Attributes attributes) throws SAXException {
// no op
}
关于super()
在IDE生成的代码中的默认调用,as@barsju
在他的注释中指出,在每个构造函数中有一个隐式调用tosuper()
(即使你没有在你的代码中编写它),这意味着,在该上下文中,调用super
的默认构造函数。 IDE
只是为你写下来,但如果删除它也会被调用。还要注意,在实现构造函数时,super()
或其带参数的任何变体(即,4037538956)只能在方法的最开头调用。
#2 热门回答(15 赞)
他们怎么知道什么时候你必须打电话给超级,什么时候你可以省略它?
通常情况下,如果一个特殊的API方法具有关键意义的底层框架范围内的生命周期,它总是会被明确说明和API文档中突出显示,如theActivity.onCreate()
API文档。此外,如果API遵循强大的设计,它应该抛出一些异常,以便在项目编译时提醒消费者开发人员,并确保它不会在运行时生成错误。
如果API文档中没有明确说明这一点,那么消费者开发人员可以认为在覆盖它时不必强制调用API方法。由消费者开发人员决定是使用默认行为(调用super
方法)还是完全覆盖它。
如果条件允许(我喜欢开源软件),消费者开发人员总是可以查看API源代码,看看该方法是如何实际编写的。例如,请查看Activity.onCreate()
sourceandDefaultHandler.startElement()
source。
#3 热门回答(7 赞)
你应该在头脑中做的测试是:
"我是否希望为我完成此方法的所有功能,然后再做一些事情?"如果是,那么你想调用314141689,然后完成你的方法。这对于"重要"方法也是如此,例如onDraw()
,它在后台处理很多事情。
如果你只想要一些功能(与你将覆盖的大多数方法一样),那么你可能不想调用super()
。