2011-02-28 124 views
6

考虑这个(匿名):匿名内部类(优于非匿名内部类)的优点是什么?

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

与此:(非匿名):

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

除更少行数,是否有任何其它优势,以匿名的形式?

是否有性能优势?

+0

匿名内部类语法是否对您而言不够详细? – 2011-03-01 07:54:46

回答

3

由于它关闭了方法的局部变量(尽管只有final当地人可用),匿名内部类与内部类相比具有优势(如问题示例代码中所示)。

通常,内部类可以很容易地转换为匿名内部类的方法,这有助于减少冗长。如果你有一个非常大的内部类,你想让它成为非本地的,你可能想要考虑与你的IDE作斗争,把它放在一个新的文件中作为外部类。

(的也是局部类,这是一个方法,并且接近了当地人中定义的正常命名的内部类。)

+0

你能解释一下你的意思吗?“关闭”。谢谢。 – an00b 2011-03-01 14:00:34

+0

@ an00b不是很好。这是一个链接:http://en.wikipedia.org/wiki/Closure_(computer_programming) – 2011-03-01 14:20:05

+0

哇!非常感谢。你刚才的答案已被接受(尽管许多其他答案也很好)。我现在要去了解什么是一流的功能,然后我将学习什么是闭包。 – an00b 2011-03-01 17:52:28

1

优点是您可以节省开发人员无需键入额外击键的时间。 :)

哦,它也可以防止你不必要为每件事物提出一个新的名称(这可能会导致在某些情况下名称冲突)。

+0

谢谢。我已经在我的问题中说过“除了少数几行”外,还包括“不要输入额外的按键”。 :)命名空间的考虑绝对是一个额外的优势。 – an00b 2011-02-28 22:17:52

+0

@ an00b:是的,我意识到这一点,但这是一个非常重要的优势,其他优势非常有限,值得一提。 :) – Mehrdad 2011-02-28 22:20:55

1

有一个缺点,即会弹出:

如果您需要在同一个内部类的不止一个,你很可能需要使用一个明确定义的类。对于你所描述的,不,你不需要一个。但是,您可能会在以后决定需要另一个具有相同功能的对象,但它们是不同的对象。

2

非匿名的好处是您可以重用该类。我相信使用匿名内部类的唯一原因是简洁。

+2

反过来,有时候您希望源代码清楚地说明给定的代码位不是一般用途,而只是在声明的位置。一个匿名类可以做到这一点。 – 2011-03-01 00:46:44

+1

你也可以用'private'内部类来做到这一点。 – 2011-03-01 16:15:19

2

我喜欢的东西有关命名的内部类:

  • 他们有一个名称。当我在堆栈跟踪中看到MyOuterClass$MyOnClickListener而不是MyOuterClass$1时,我发现调试起来更容易,这是您使用匿名内部类获得的结果。
  • 它有时有助于将内部类的实际代码从您使用它的地方分离出来。我特别喜欢这个,如果我已经在一个很长的方法或缩进超过一个或两个级别。

要评论你关于性能的观点,匿名内部类会被编译到正常的类中,所以应该没有性能差异。

0

匿名类的目的是让你所需的类地方。当我们非常确定某个特定的类A是B类的唯一消费者,并且没有其他地方可以使用这个B类时,就使用匿名类。那么我们最好将该类B定义为名称类A中的匿名类。在相同的类中写入所需的逻辑,以避免从外部创建对象。在代码可维护性方面很容易维护。所以匿名类可以让你的代码更加简洁。它们使您能够同时声明和实例化一个类。除了没有名字之外,它们就像本地的课程。如果您只需要使用一次本地课程,请使用它们。