2012-04-20 56 views
101

当我制作属于我自己的Android自定义类时,我的原生类是extend。然后,当我要重写基方法,我总是叫super()方法,就像我一直做onCreateonStop当重写时不调用super()方法?

而且我认为这是它,因为从一开始Android团队建议我们始终每个方法覆盖请致电super

但是,在很多书我可以看到,开发商,比我更有经验,往往忽略调用super,我真怀疑他们做它作为一个知识的缺乏。例如,看一下这个基本SAX分析器类,其中superstartElementcharactersendElement省略:

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。不要拘泥于这个特定的例子。这只是从很多例子中随机挑选的一个例子。

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

+3

endElement的API文档中提到“默认情况下,不做任何事情,应用程序编写者可以重写此方法...”,这意味着您可以安全地调用super,因为它“没有”,但您不必你真的可以覆盖它。如果您阅读该方法的文档,您可以经常分辨是否必须/可以/不应该这样做。 – zapl 2012-04-20 11:07:57

+1

小例子:我在启动画面中使用onBackPressed(),并且我不会调用超级,所以它不会熄灭,它只是禁用按钮。 – 2012-04-25 03:10:36

+0

@sandalone对不起,在这里提问,但是您是否有任何关于如何通过应用内结算处理增值税的经验,以及哪些国家/地区是由Google自动完成的,哪些国家/地区需要手动上报/缴纳增值税税?请参阅http://stackoverflow.com/questions/36506835/android-in-app-billing-vat-tax – 2016-04-08 18:51:37

回答

130

通过调用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()的呼叫将执行save()逻辑两者AB,在这个特定的顺序。如果您在B.save()之内没有拨打super.save(),则不会调用A.save()。如果您在save(b)之后拨打super.save(),A.save()之后会有效执行B.save()

如果你想覆盖super的行为(即,完全忽视它的实施,并提供一切你自己),你不应该叫super

在您提供的SAXParser示例中,implementationsDefaultHandler这些方法只是空的,以便子类可以覆盖它们并为这些方法提供行为。在这个方法的javadoc这也是指出。

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

关于通过集成开发环境生成代码的super()默认电话,在他的批评是@barsju指出的那样,在每个构造有以super()(即使你没有在你的代码写),隐式调用它在这种情况下,意味着拨打super的默认构造函数。 IDE只是为你写下来的,但如果你删除它也会被调用。另外注意,在实现构造函数时,super()或其任何带参数的变体(即super(x,y,z))只能在该方法的开头处调用

+14

也没有注意到,对于构造函数'super()'(超类的默认构造函数)总是被调用,甚至如果你没有指定它。如果超类没有默认的构造函数,如果您没有显式调用超类的构造函数之一作为子类构造函数中的第一条语句,将会得到编译错误。 – barsju 2012-04-20 10:55:59

+1

是的,它基本上只是懒惰 - 我们知道的方法不做任何事情只是为了简洁省略 – Voo 2012-04-20 10:59:33

+1

感谢您的宝贵意见,@ barjsu,我已经在答案中包含了这些细节。 – 2012-04-20 11:09:26

3

哈维给了一个更好的答案..但你也许可能会知道是什么super()做一个重写的方法......它的广告你有什么用默认的行为做..

如调用时:

onDraw() 

在重写时,视图类方法..你说super.onDraw(前画的东西),它出现一次的观点是完全画..所以在这里呼吁super是必要的,因为Android有一些非常重要的事情做(像onCreate())

,但在同一时间

onLongClick() 

当你重写这个你不想叫超,因为它带来了一个对话框,为一个EditText上或任何其他类似的视图选项列表..多数民众赞成基本差异..你可以选择离开一段时间..但对于其他方法,如onCreate() , onStop(),你应该让操作系统处理它..

2

我没有清楚地问你的问题,但如果你问为什么不拨打super方法:

调用super方法是有原因的:如果在父类中没有零参数构造函数,那么就不可能为它创建子类,所以要么在父类中保留一个无参数构造函数,要么您需要在子类构造函数的顶部定义super()调用语句argument(how much argument constructor you have used in super class)

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

7

,你应该在你的头做的测试是:

“难道我想这一切方法为我做的功能,然后做一些事情之后?”如果是,那么你想打电话给super(),然后完成你的方法。对于诸如onDraw()等“重要”方法来说,这是很正确的,后者在后台处理很多事情。

如果您只想要一些功能(与大多数方法一样,您将覆盖),那么您可能不想拨打super()

15

他们怎么知道你什么时候必须打电话超时,什么时候可以省略打电话?

通常,如果一个特殊的API方法对底层框架上下文生命周期有重要意义,它总是会在API文档中明确陈述和突出显示,如Activity.onCreate() API documentation。此外,如果API遵循健壮的设计,它应该在项目编译时抛出一些异常来提醒消费者开发人员,并确保它在运行时不会产生错误。

如果在API文档中没有明确说明这一点,那么消费者开发人员认为在覆盖它时不强制调用API方法是非常安全的。由消费者开发人员决定是否使用默认行为(调用super方法)或完全覆盖它。

如果条件允许(我喜欢开源软件),消费开发人员可以随时查看API源代码并查看该方法实际上是如何编写的。例如,请查看Activity.onCreate() sourceDefaultHandler.startElement() source

+0

感谢您向我解释其他内容。感谢您提醒我检查源代码。 – sandalone 2012-04-21 15:17:57

2

我实现像

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; 
    } 
} 

约束数组列表如果你看一下代码,它根本实际上是让超类之前的一些预检执行实际添加元素到列表中。 这告诉的两倍原因方法重载之一:要扩展什么超阶级可以做

  • 特异性您希望通过多态性添加特定的行为,如在普通动物

    1. 扩展王移动语义学的例子,鸟类移动(飞)和青蛙移动(跳)的方式是特定于每个子类的。
  • 相关问题