扩展接口与通过匿名类实例化 [英] Extending an Interface vs Instantiating via Anonymous Class

查看:106
本文介绍了扩展接口与通过匿名类实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我知道这很危险地接近许多其他问题。但是,我没有看到任何与Android的OnClickListener接口无关的内容。我在一般意义上问。

NOTE: I am aware that this is dangerously close to many other questions. I haven't seen any, however, that do not pertain specifically to Android's OnClickListener interface. I am asking in a general sense.

我理解通过匿名类实例化接口之间的区别...
a la:

I understand the difference between instantiating an interface via an anonymous class... a la:

private final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        draw();
    }

};

...并扩展界面。

public class ClassyClass implements Runnable {
    ...
    //do other cool stuff here
    ...
    @Override
    public void run() {
        draw();
    }
    ...
    //and more here
    ...

}

但是,除了 OnClickListener 等界面带来的明显好处之外,这两种方案都有很大的优势吗?

But, other than the obvious benefits from interfaces such as OnClickListener is there a strong advantage to either option?

我认为扩展它将是显而易见的选择,因为你已经在创建该对象 - 没有重复工作。这是对吗?

I would think that extending it would be the obvious choice because you are already creating that object - no duplication of effort. Is this right?

我在一般意义上问,但是,因为我目前正在使用 Runnable ,如果它从我喜欢的任何一种选择中看到了优势。

I am asking in a general sense but, as I am currently working with Runnable, if it has sees an advantage from either option I'd love to know.

推荐答案

这里有一个显示主要差异的例子。这有点人为,但只是为了说明。

Well here is an example that shows the main differences. It's a little contrived but it's just to illustrate.

这是一个匿名版本:

class PrintBuilder {
    List<Runnable> printers = new LinkedList<>();

    List<Runnable> get() {
        return printers;
    }

    PrintBuilder add(final String line) {
        printers.add(new Runnable() {
            public void run() {
                System.out.println(line);
            }
        });

        return this;
    }
}

这是一个嵌套版本:

class PrintBuilder {
    List<Printer> printers = new LinkedList<>();

    PrintBuilder add(String line) {
        printers.add(new Printer(line));
        return this;
    }

    List<Printer> get() {
        return printers;
    }

    static class Printer implements Runnable {
        String line;

        Printer(String line) {
            this.line = line;
        }

        public void run() {
            System.out.println(line);
        }
    }
}

所以你可以看到主要的差异在于:

So you can see the main differences are then:


  • 匿名类是内部的,它具有对封闭实例的隐式引用。

特别是,在上面的例子中,PrintBuilder被泄露,直到内部Runnable对象死亡。在第二个例子中,Runnable类是静态的,所以它没有这个问题。

In particular, in the above example, the PrintBuilder is leaked until the inner Runnable objects die. In the second example, the Runnable class is static so it doesn't have this problem.


  • 匿名类有点短。

匿名类不需要字段和构造函数,因为它们是隐式的。

An anonymous class doesn't need fields and constructors because they are implicit.


  • 代码组织方式的巨大差异。

在实例化的地方声明一个匿名类如果匿名类不是很短,这对封闭类的布局会非常具有破坏性。另一方面,如果匿名类很短,那么类似函数的语法就很好。

An anonymous class is declared where it's instantiated and this can be pretty destructive to the layout of the enclosing class if the anonymous class isn't very short. On the other hand if the anonymous class is short, the functional-like syntax is nice.

此外,所有类都会增长,根据我的经验,这可以转为当匿名课程变得太大时闻起来。匿名类也很难重构到顶级类。

Also all classes tend to grow and in my experience this can turn in to a smell when an anonymous class gets too big. Anonymous classes are also much more difficult to refactor in to a top-level class.

这篇关于扩展接口与通过匿名类实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆