Is possible to create objects of an abstract class in Java
It depends on what you mean.
If you mean: "can I have an instance of an abstract class" -- sure; any instance of a concrete subclass (of an abstract class) implicitly is an instance of the abstract super type too.
If you mean: "can I have an instance of an abstract class without defining a concrete subtype" -- yes, if some library (for example javassist, cglib) generates a concrete subtype for you.
If you mean "will the following expression ever pass":
assert Modifier.isAbstract(x.getClass().getModifiers());
the answer is no.
You cannot instantiate an abstract class (calling new
on it), if that is what you mean.
It is possible to have instances of subclasses. Those objects are also instanceof
the abstract class, meaning that you can cast them to it.
An attempt to instantiate an abstract class will fail at compile time unless you provide the implementation of all its abstract methods (by implementing an anonymous inner class):
Runnable r = new Runnable() {
public void run() {
//do something
}
};
If you had an abstract class like this:
public abstract class Foo
{
public void bar()
{
car();
}
protected abstract void car();
}
if you were able to do this:
final Foo foo;
foo = new Foo();
foo.bar();
what would happen when the "bar" method called the "car" method given that the "car" method has no code associated with it?
You can do this however:
class Star
extends Bar
{
protected void car()
{
}
}
and then do:
final Foo foo;
foo = new Star();
foo.bar();
This time you have a variable of type Foo that can hold any concrete subclass of Foo (a class that is not abstract is concrete). Now when you call the "bar" method it uses the one in Foo, and when the "car" method is called it uses the one in Star. That is an example of polymorphism.
Assuming this is a complete newbie question, here's what abstract classes are in Java:
There's three main types of classes in java, interfaces, abstract classes and classes. Each of these adds something specific to the actual class definition;
- Interface defines the methods one can find (and must implement) in a class. In short, interfaces define behaviour.
- Abstract classes implement some functionality and on top of that define additional abstract methods which must be implemented by the classes extending. Using abstract classes is similar to direct class inheritance.
- Classes are just, well, classes which you most likely are already familiar with.
There's plenty of reasons for using any of the possible class types, however most commonly in modern Java code you will see a lot of interfaces and a bunch of classes implementing those interfaces.
Examples: Class
Consider the following class:
public class Cat {
public void speak() {
System.out.println("Meow!");
}
public void eat(Food f) {
System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
}
}
This is a very simple class and the kind every Java coder, even the beginners, are familiar with. Nothing special here. However with this you have an issue: what if you have a Dog
that's basically the same but it obviously barks instead of meows?
Example: Abstract class
The "Cat
or Dog
" problem can be solved with inheritance. Traditionally standard inheritance looks like this:
public class Animal {
public void eat(Food f) {
System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
}
}
public class Cat extends Animal {
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
public void speak() {
System.out.println("Bark! Bark!");
}
}
However herein lies a problem: To actually make the Cat
meow or the Dog
bark, you have to have code which checks what kind of animal exactly the animal is, cast it to correct type and then call the method:
if (animal instanceof Dog) {
((Dog) animal).speak();
} else if (animal instanceof Cat) {
((Cat) animal).speak();
}
As you can see, this sort of code is completely pointless! Surely we would like to just be able to call animal.speak()
directly, right? And for that purpose, we have abstract classes! By replacing the Animal
class in the example above with this
public abstract class Animal {
public void eat(Food f) {
System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
}
public abstract void speak();
}
you can make your Dog
bark and Cat
meow just by calling animal.speak()
! Great, isn't it?
Note that you could also define the default behaviour of speak()
to Animal
and then just override that method in Cat
and Dog
and sometimes that even does make sense more than what I just showed here.
Anyway, another problem arises: What if your Dog
is an Animal
and also a Pet
? Java only allows for single inheritance to avoid diamond inheritance problem so you can't just have another superclass for them. You could add it as a superclass for Animal
but then again, not all animals are pets - there certainly isn't a hippo in my yard pond!
Example: Interface
Since interfaces only define behaviour instead of actually implement them (and that's actually the related keyword!) you can use interfaces to define additional behaviour to your original class. Lets assume that pets generally can be groomed among other things, so the interface for Pet
would be like this:
public interface Pet {
void groom(Brush b);
}
Now just add implements Pet
to your Dog
and it's now groomable! Just to make sure, the first line of your Dog
class should look like this:
public class Dog extends Animal implements Pet {
Now to groom your Dog
or any other Pet
you can do this:
if (animal instanceof Pet) ((Pet) animal).groom();
That's pretty much it. As an exercise, try implementing Animal
as an interface; do note that interfaces can actually extend other interfaces.
PS. Also enums and anonymous inner classes can be considered as class types, however they're not quite the main ones everyone should know right after learning the basics of Java.