澄清

2011-02-28 224 views
2

匿名内部类请求,而在Android学习TTS,我碰到下面的代码片段:澄清

speakBtn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null); 
     }}); 

我真的很新的Java,所以在确定各种构建我的信心水平不那很棒。我认为我上面看到的是Anonymous Inner Class,但'新的OnClickListener()'令我感到困惑。因此,请确认和/或更正以下任何理解:

  1. 内部类在新的OnClickListener()后定义为 。
  2. OnClickListener是一个超级类 ,从中派生出内部类 。
  3. (匿名)内部类只有 一个成员函数:OnClick()。
  4. 什么是@Override内部类的 定义?如果 这是一个注释,那么我 困惑为this answer状态 匿名内部类不能 被注释。

最后,有没有办法用像我这样的n00b更容易破译的方式来编写上面的代码片段?

回答

4
  1. 是;它在大括号之间定义。
  2. 是的,除了它是一个接口,而不是一个类。
  3. 是的。
  4. 您不能添加级别的注释。
    @Override是一个方法级别注释,它工作正常。
1
  • 内类的定义右后新OnClickListener()。

想象那里的代码描述了OnClickListener()的一个未命名的子类。类的定义在括号内,就像你想的那样。

  • OnClickListener是从中派生内部类的超类。

  • 的(匿名)内类只有一个成员函数:的OnClick()。

确实如此,但事实并非如此。它可以有更多的成员函数。

  • 什么是@Override里面的内部类的定义?如果这是一个注释,那么我很困惑,因为这个答案指出匿名内部类不能被注释。

@Override用于对方法进行编译时错误检查。您可以在匿名内部类上使用方法级别注释。

2

下面就来重写你的代码片段,使得它更加清晰“以一个小白” :)

class MyOuterClass { 
    private class MyOnClickListener implements OnClickListener { 
     @Override 
     public void onClick(View view) { 
      mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null); 
     } 
    } 

    // later (inside some method)... 
     speakBtn.setOnClickListener(new MyOnClickListener()); 
} 
3

好了,基本上这个片段的代码创建其名称是由编译器为您的舒适错位一类的方式所以你不需要关心自己的命名。该类将实现接口OnClickListener,并包含onClick(View)方法的实现,如接口所需。

因此,您的片段可能是writter某种程度上是这样的:

class OnClickListenerThingy01 implements OnClickListener { // name is invented from the top of my head and corresponds actual name manging in no way 
    @Override 
    public void onClick(View view) { 
     mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null); 
    } 
} 
speakBtn.setOnClickListener(new OnClickListenerThingy01()); 

@Override批注没有放置在类本身 - 它在你的代码中没有声明可以添加注释,是编译器生成 - 但在方法上。

@Override注释用于标记覆盖(多么令人惊讶)和方法实现。它的主要用途是在重写方法的签名发生变化时生成一个编译器错误,但是你不能相应地更新重写声明,这样当覆盖失败时你不会感到惊讶,因为比如说重写被重命名。

在接口实现的情况下,如果您忘记完全实现一个接口,编译器会生成一个错误,所以@Override可能看起来有点多余,但事实并非如此。事实上,让不必要的方法(例如,从接口中删除方法声明)不会留在代码中是一件相当不错的事情。

虽然必须指出像Eclipse这样的IDE很可能会使这些问题无效,因为提供的重构工具足以避免这种情况。无论如何,@Override在使用它的时候对你有很好的方法。

0

OnClickListener是 一个超类的内部类派生

不是真的:OnClickListener是不是一类。 此语法用于创建实现接口OnClickListener的新(匿名)类的实例。所以你只有一个方法来实现:onClick()。

+0

是不是一个接口(虚拟抽象)类? – an00b 2011-02-28 19:25:31

+0

是的,你是对的。一个接口是一个完全抽象的类。但是为了不混淆,我们不认为接口是一个类;) – 2011-02-28 19:37:15