Java: creating a reference type from an abstract class and interface
I'm new to Java and I've read the threads ( here ) that it is not possible to instantiate an abstract class. So I checked it out.
The first test I did is shown below. And it looks like I can actually create an abstract class, and in fact I have a new typewhich belongs to an abstract class and the type is actually shared by all subclasses that extends it. It also means polymorphism is applied.
import java.util.*;
abstract class AbstractClass{
public abstract void printname();
}
class Test1 extends AbstractClass{
private String name;
public Test1(String name){
this.name = name;
}
public void printname(){
System.out.println("My name is " + name);
}
}
class Test2 extends AbstractClass{
private String saysomething;
public Test2(String saysomething){
this.saysomething = saysomething;
}
public void printname(){
System.out.println(saysomething);
}
}
class TestingApp{
public static void main(String[] args){
AbstractClass[] abstractclass_list = {new Test1("JEFFFFFF") , new Test2("Hey , say something")};
for(AbstractClass item : abstractclass_list){
item.printname();
}
}
}
Then I did another test, but this time instead of working on an abstract class, I decided to create an interface-specific type. It looks like I can create an interface. I can actually create a type that references an interface. This type is used by all classes that implement this interface. And polymorphism is applied again.
import java.util.*;
interface AbstractInterface{
public void printname();
}
class Test4 implements AbstractInterface{
private String name;
public Test4(String name){
this.name = name;
}
public void printname(){
System.out.println("My name is " + name);
}
}
class Test3 implements AbstractInterface{
private String saysomething;
public Test3(String saysomething){
this.saysomething = saysomething;
}
public void printname(){
System.out.println(saysomething);
}
}
class TestingAbstractInterfaceApp{
public static void main(String[] args){
AbstractInterface[] abstract_list = {new Test4("Helen") , new Test3("Hey , say my name")};
for(AbstractInterface item : abstract_list){
item.printname();
}
}
}
Question:
I feel like there is something wrong with what I am doing in my code. But I can't explain why the code still works when, in theory, it's impossible to instantiate an abstract class and interface. Am I really creating an abstract class and interface in the examples shown above? As this is similar to what I did, as I have a new type for the abstract class and interface. Please correct me if my logic is wrong or if I am using the wrong words.
Update: I think my misunderstanding is about the type... I've always thought that a type can only refer to normal Java classes and not abstract classes and interfaces. How does "type" work? Is this link building?
source to share
Why do you think that you are actually creating AbstractClass
and AbstractInterface
?
new Test1("JEFFFFFF") , new Test2("Hey , say something"), new Test4("Helen") , new Test3("Hey , say my name")
- all instances of concrete classes, not abstract ones.
If you are citing AbstractClass[] abstractclass_list =
as proof of creating instances of abstract classes, it is wrong. Here you are declaring an array whose elements are of type AbstractClass
a Test1
and Test2
- (since they are extend AbstractClass
).
UPDATE
You can have something like this AbstractClass abs = new Test1("hey");
, and it does it by creating a new instance of the class Test1
, and it refers to that instance from a variable abs
. abs
concrete type Test1
, but only the methods declared in the AbstractClass
. If you want to call methods Test1
, you will need to transfer it first.
AbstractClass abs = new Test1("hey");
abs.printname(); // this is ok, and it calls `printname() implemented in Test1
abs.someTest1Method(); // this is NOT ok, someTest1Method() is not visible to abs
((Test1)abs).someTest1Method(); // this is ok, abs is cast to Test1, but would fail if abs was instantiated as 'abs = new Test2("t2")' (would throw ClassCastException)
source to share
You are not creating an abstract class or your interface. You create concrete classes that extend your class abstract ( Test1
and Test2
) or implement your interface ( Test3
and Test4
).
This made it possible to assign an instance of a concrete class to a variable whose type is an interface or an abstract class. In fact, it was even encouraging.
source to share
You are not creating an abstract class or an interface. You are just using the built-in subclass to superclass promotion ability.
Ignoring the array and using only the first object would be equivalent to implicit upcasts:
AbstractClass myObject = new Test1("JEFFFFFF");
and
AbstractInterface myObject = new Test1("JEFFFFFF");
So in the code:
AbstractClass[] abstractclass_list = {
new Test1("JEFFFFFF") ,
new Test2("Hey , say something")};
You create objects of concrete classes Test1
and Test2
- the array contains references to the base (and general) abstract base class.
Similarly, in the second example, you get an array of interface references.
source to share
In short, I would like to say that Parent(here, Abstract/Iterface)
may be referred to by him child(here, concrete class)
.
So, a reference variable can refer to an instance of a child class.
Just memorize this concept in your brain, it will fix all your Dynamic Dispatcher, Inheritance related .... !!!
source to share
You are not instantiating
a abstract
and interface
,
you are instantiating
some specific of implementations
this class abstract
and this interface
.
If you are declaring a list AbstractClass
or AbstractInterface
, you can simply call methods that are declared in your superclass or interface but are not listed in your concrete implementations (Test1, Test2, Test3, and Test4).
source to share