这两个匿名类声明有什么区别

时间:2015-10-24 17:39:24

标签: java anonymous-inner-class

我无法找到这两个匿名类声明之间的差异。

class Boo {
       Boo(String s) { }
       Boo() { }
    }
    class Bar extends Boo {
       Bar() { }
       Bar(String s) {super(s);}
       void zoo() {
           Boo f = new Boo() {                       // Line-1
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };
       }
    }


class Boo {
       Boo(String s) { }
       Boo() { }
    }
    class Bar extends Boo {
       Bar() { }
       Bar(String s) {super(s);}
       void zoo() {
           Boo f = new Boo("Random String") {         // Line-2
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };
       }
    }


我理解的是,匿名类是类Boo的子类,其实例由引用变量f多态引用。但它在使用no-args构造函数(Line-1)和参数化构造函数(Line-2)方面有何不同。

2 个答案:

答案 0 :(得分:3)

  • 它指出Boo中定义了多个构造函数。

并且

 Boo f = new Boo("Random String") {         // Line-2
               void method()
               {
                   System.out.println("Inside anonymous");
               }
           };

由于它是一个匿名类,并且立即提供了实现,因此没有人使用该字符串,并且那里的字符串传递是多余的。

答案 1 :(得分:2)

让我们为你的课程添加一些“肉”,看看有什么区别。更改Boo,以便它实际上对字符串执行某些操作:

class Boo {
    private String s = "Default";

    Boo(String s) {
        this.s = s;
    }

    Boo() {
    }

    protected String getString() {
        return s;
    }
}

现在它存储了字符串,任何子类都可以通过getString()方法检索该字符串。

现在展开我们的Bar

class Bar extends Boo {
    Bar() {
    }

    Bar(String s) {
        super(s);
    }

    void zoo() {
        Boo anon1 = new Boo() {                       // Line-1
            void method()
            {
                System.out.println("Inside anonymous");
            }
            @Override
            public String toString() {
                return "First anonymous subclass of Boo with value " + getString();
            }
        };
        Boo anon2 = new Boo("Some Random Value") {    // Line-2
            void method()
            {
                System.out.println("Inside anonymous");
            }
            @Override
            public String toString() {
                return "Second anonymous subclass of Boo with value " + getString();
            }
        };
        System.out.println(anon1);
        System.out.println(anon2);
    }
}

所以我在同一个方法中创建了两种类型的匿名类,然后我打印它们。请注意,我已为每个匿名类添加了toString方法。 toString方法在其返回的值中使用getString中的Boo

现在,当您致电new Bar().zoo()时会发生什么?

你得到了输出

First anonymous subclass of Boo with value Default
Second anonymous subclass of Boo with value Some Random Value

所以第一个对象anon1是用Boo的无参数构造函数创建的。因此,私有s的值为Default。这反映在toString()方法中。第二个对象是使用Boo的其他构造函数创建的,它为s提供了不同的值。现在这个价值成了印刷价值的一部分。

因此,当构造函数实际执行某些操作,并且匿名类使用构造函数中传递的信息时,如果传递参数,则会产生影响。

备注

  • Bar本身也是Boo的子类,但在您的示例中,它没有任何区别。它可能是一个完全独立的阶级。
  • 方法method()从未使用过,不能使用(除了反射等),因为对匿名类的唯一引用是通过类型Boo,它没有可继承的{{1} }}。除非继承或覆盖该方法,否则不能从超类引用中调用子类的方法。