0

可能重复:
面试:我们可以实例化抽象类吗?

我有一个定义了所有方法的抽象类(即其中不包含抽象方法),如下所示:

public abstract class MyAbstractClass {
  String s;
  public void setString(String s) {
    this.s = s;
  }
  public String getString() {
    return this.s;
  }
}

还有一个 JUnit 测试类:

public class TestClass {

  MyAbstractClass c;
  @Before
  public void setUp() {
    // What is happening here? And why does this work with an abstract class?
    // Instantiation? Extending the abstract class? Overwriting?
    c = new MyAbstractClass() { };
    // This will not work: (Why?)
    // c = new MyAbstractClass();
  }

  @Test
  public void test_AllMethodsAvailable() {
    // Why can I access the abstract class' methods?
    // Shouldn't they be overwritten? Or did I extend the class?
    c.setString("Test");
    assertEquals("Test", c.getString());
  }
}

我不太明白为什么分配给c在第一种情况下有效但在第二种情况下无效,或者那里实际发生了什么(因此,为什么访问抽象类的方法在测试中有效)。

有人可以解释一下(并可能指向我解释为什么这样做的Javadoc,文章或书籍)吗?

为什么我可以在那里“实例化”一个抽象类?(这实际上是我在做什么?)

它与内部类有关吗?

4

4 回答 4

2

您正在使用该代码创建一个匿名内部类。您以这种方式创建的类是隐式扩展MyAbstractClass的。

由于您的abstract类没有abstract方法,因此您不必提供实现,因此可以使用。

如果您不了解内部类,可以查看官方文档,我认为这非常好。

于 2013-01-28T12:32:08.910 回答
1

它与内部类有关吗?

 c = new MyAbstractClass() { };

绝对,上面是匿名内部类声明,你并没有真正实例化一个抽象类(你不能),但你实际上是在创建一个匿名内部类a sub-type of MyAbstractClass

于 2013-01-28T12:33:21.837 回答
0

当您编写时c = new MyAbstractClass() { };,您实际上创建了一个匿名类,它扩展了MyAbstractClass,并且不是抽象的。由于MyAbstractClass已经定义了所有方法,因此实例化是有效的。

于 2013-01-28T12:33:29.513 回答
0

您对 c 的分配有效,因为您正在使用匿名非抽象类对 MyAbstractClass 进行子类化, c 是非抽象类的实例。

由于您的抽象类中没有任何抽象方法,因此您的匿名类不必实现任何东西。

于 2013-01-28T12:34:42.680 回答