How does this Java code instantiate an abstract class?
I am making changes to a Java class and I noticed the following line of code:
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
What I find strange about this line is that it OurClass
is an abstract class - here's the definition OurClass
:
public abstract class OurClass<T extends OurInterface1> implements OurInterface2<T>
When I delete {}
at the end of the line, Eclipse tells me Cannot instantiate the type OurClass<OurInterface1>
, but when I put {}
back, everything is fine.
How does {}
it allow you to instantiate an abstract class?
source to share
The addition {}
introduces the syntax for the anonymous inner class .
The anonymous class expression consists of the following:
New operator
The name of the interface to implement, or the class being extended. In this example, the anonymous class implements the HelloWorld interface.
Parentheses containing arguments to the constructor, as an expression expression for an instance of a regular class. Note. When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example.
The body that is the body of the class declaration. More specifically, method declarations are allowed in the body, but are not instructions.
You are declaring an anonymous inner class that you subclass OurClass
. The body of this class is empty: {}
. This anonymous inner class is not abstract
, so you can create one.
When you delete {}
, the compiler thinks that you are directly creating OurClass
, the class abstract
, so it disallows it.
source to share
In fact, you can extend and override methods on the fly when you instantiate an interface or extendable class. This is called anonymous inner class.
What you did in your example was to create an anonymous inner class, but that had no effect because you didn't override anything. You could put the overridden methods in these curly braces {}
.
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
The commonly used use of an anonymous inner class is on an interface Runnable
that defines a single void method run()
. You can implicitly instantiate an object that implements Runnable
and overrides run()
on the fly.
Runnable someTask = new Runnable() {
@Override
public void run() {
System.out.println("Running a task!");
}
};
Anonymous inner classes are disliked by many developers because they are quite verbose. Fortunately, in Java 8, you can use lambda expressions to replace most of the anonymous inner classes that implement a single method. The compiler is basically an anonymous inner class for you to write code more concisely.
Runnable someTask = () -> System.out.println("Running a task!");
source to share
You cannot instantiate an abstract class without implementing abstract functions within the class. This is usually done by creating abstract classes with an embedded class. See https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
In your case, the {} used after instantiation allows you to implement any abstract function in the abstract class.
For example,
Consider
public abstract class DummyClass {
abstract void test() ;
}
- an abstract class with an abstract function.
The class can be initiated:
DummyClass d = new DummyClass(){
void test(){
//test() implementation here
}
} ;
Hope this helps! :)
source to share