【问题标题】:How does this Java code instantiate an abstract class?这个 Java 代码如何实例化一个抽象类?
【发布时间】:2015-04-29 23:05:56
【问题描述】:

我正在对我们的 Java 类进行更改,我注意到以下代码行:

OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};

我觉得这行奇怪的是OurClass 是一个抽象类 - 这是OurClass 的定义:

public abstract class OurClass<T extends OurInterface1> implements OurInterface2<T>

当我删除行尾的{} 时,Eclipse 告诉我Cannot instantiate the type OurClass&lt;OurInterface1&gt;,但是当我把{} 放回去时,一切正常。

{} 如何让你实例化一个抽象类?

【问题讨论】:

    标签: java class syntax instantiation abstract


    【解决方案1】:

    添加{} 引入anonymous inner class 的语法。

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

    • 新的运算符

    • 要实现的接口或要扩展的类的名称。在这个例子中,匿名类实现了 HelloWorld 接口。

    • 包含构造函数参数的括号,就像普通的类实例创建表达式一样。注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,如本例所示。

    • 主体,即类声明主体。更具体地说,在主体中,允许方法声明,但不允许声明。

    您正在声明一个匿名内部类,它是OurClass 的子类。这个类的主体是空的:{}。这个匿名内部类不是abstract,所以你可以实例化它。

    当您删除{} 时,编译器认为您正在直接实例化OurClass,这是一个abstract 类,因此不允许它。

    【讨论】:

      【解决方案2】:

      当您实例化接口或可扩展类时,您实际上可以动态扩展和覆盖方法。这称为匿名内部类。

      您在示例中所做的是创建一个匿名内部类,但它没有任何效果,因为您没有覆盖任何东西。您可以将覆盖的方法放在大括号 {} 中。

      OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {}; 
      

      匿名内部类的一个常用用法是在Runnable 接口上,它定义了一个单独的void run() 方法。您可以隐式实例化一个实现 Runnable 的对象并即时覆盖 run()

      Runnable someTask = new Runnable() { 
          @Override
          public void run() { 
              System.out.println("Running a task!");
          }
      };
      

      许多开发人员不喜欢匿名内部类,因为它们非常冗长。幸运的是,在 Java 8 中,您可以使用 lambda 表达式来替换大多数实现单个方法的匿名内部类。编译器基本为你推断出匿名内部类,让你写代码更简洁。

      Runnable someTask = () -> System.out.println("Running a task!");
      

      【讨论】:

        【解决方案3】:

        调用new 操作符(new OurClass&lt;OurInterface1&gt;() {}) 之后的代码块实际上是创建一个扩展OutClass 的匿名类的实例。

        由于这个类不再是abstract,所以实例化它没有问题。

        【讨论】:

          【解决方案4】:

          如果不实现类中的抽象函数,就无法实例化抽象类。这通常是通过用已实现的类实例化抽象类来完成的。 参考:https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

          在您的情况下,实例化后使用的 {} 允许您在抽象类中实现任何抽象函数。

          例如,

          考虑

          public abstract class  DummyClass {
           abstract void test() ; 
          

          }

          是具有抽象功能的抽象类。

          该课程可以由以下人员发起:

          DummyClass d = new DummyClass(){
                 void test(){
                       //test() implementation here 
                  }
              } ;
          

          希望这会有所帮助! :)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-08
            • 2019-08-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-06
            • 1970-01-01
            • 2015-07-11
            相关资源
            最近更新 更多