为什么我们在Java中使用带有接口的“new”关键字?

时间:2013-03-26 15:51:56

标签: java android oop

我是Android新手。我已经学习了基本的面向对象编程课程,这些课程为课程提供了一种增强功能的方法。实际上以这种方式增强其功能的类,实现这些接口并覆盖在接口中编写的所有方法。

以下代码在Android中执行相同的工作:

public class MyActivity extends Activity implements OnClickListener {
   // All other code you may expect

   myButton.setOnClickListener(this);

   @override
   public onClick(View view) {
      // Code when view is clicked
   }
} 

这段代码是可以理解的。但是下面的代码对我来说没有任何意义,我在不同的地方搜索过但没有得到满意的答案。

public class MyActivity extends Activity {
   // All other code you may expect

   myButton.setOnClickListener(new OnClickListner() {

      @override
      public onClick(View view) {
         // Code when view is clicked
      }
  });
}

现在,OnClickListener()是Android文档中所述的界面,现在我们正在实例化一个界面。不是只实现接口吗?请帮我理解这一点。

4 个答案:

答案 0 :(得分:11)

new OnClickListner() {没有实例化接口,它声明了anonymous inner class。基本上是一个匿名类(实现接口OnClickListner的类),它本身没有名称。

来自Documentation

匿名类表达式包含以下内容:

  • 新操作员
  • 要实现的接口的名称或要扩展的类。在此示例中,匿名类正在实现OnClickListner接口。
  • 包含构造函数参数的圆括号,就像普通的类实例创建表达式一样。注意:在实现接口的情况下,没有构造函数,因此您使用一对空括号,如本例所示。
  • 一个正文,它是一个类声明体。更具体地说,在正文中,方法声明是允许的,但语句不是。

答案 1 :(得分:1)

那些OnClickListeners是匿名类。括号包括类定义。

答案 2 :(得分:1)

如果将new与接口一起使用,则必须在{ }块中通过接口覆盖方法providerd,同时创建实现接口但没有自己名称的anonymous inner class

这允许您例如具有多个不同的点击处理程序,而无需为每个按钮创建实现OnClickListner的类。

答案 3 :(得分:1)

实际上,这是我在OOP中见过的最糟糕的做法之一,而不仅仅是java。

基本上,您从Interface创建匿名内部类,您必须立即实现接口提供的所有方法。在这种情况下,将接口视为抽象类(它基本上总是或多或少)。

虽然广泛传播并且受到某些语言的适当支持,但java仅支持 language 级别的内部类的概念。 但是,在字节代码级别,没有内部类。编译器将这些内部类语言结构从其父类中删除,除了它们之外还使用$ -sign和连续数字将它们作为兄弟,并将私有范围元素(方法,变量)提升到包范围。 现在让它沉入片刻并考虑安全隐患。

接下来的事情是,这些匿名内部类,因为它们在Android上下文中过度使用(原始问题被标记为Android)完全混乱了代码并使其完全无法读取。这远离 clean code ,我强烈建议遵循这些代码以保持易于阅读和维护的代码。

另一件事是每个new Interface() { ... };自然地创建一个新对象。通常,您会在Android世界中与听众一起看到这一点。如果您有多个监听器,请为自己和用户节省一些内存,并使用交换机实现一个对象...不要每次都创建一个新对象,因为Google示例会这样做,并且因为有人在他们的示例中执行此操作在SO和教程或论坛中。 :)