Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Creating Reference Type from Abstract class and interface

I am new to Java and I have read threads (here) that it is not possible to instantiate an abstract class. So, I tested it out.

The first test I did is shown below. And it seems like I can actually instantiate an abstract class and in fact, I actually have a new type which refers to the abstract class and the type is actually shared by all subclasses the extends it. This also means polymorhpism applies.

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 abstract class, I decided to create a type which refers to Interface. It seems like I can instantiate an interface as well. I can actually create a type that refers to the interface. This type is shared by all the classes that implements this interface. And polymorphism applies 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 am sensing there is something wrong with what I am doing in my code. But I cannot quite explain how come the code still works when theoretically, it is impossible to instantiate an abstract class and interface. Am I actually instantiating an abstract class and an interface in the examples shown above ? Because this seems like exactly what I have done, 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: SO I guess my misunderstanding is about type. I always thought type can only refer to normal Java classes but not abstract classes and interfaces. How does "type" actually work? Is it creating a reference?

like image 626
mynameisJEFF Avatar asked Jan 17 '26 14:01

mynameisJEFF


1 Answers

Why do you think you are actually instantiating AbstractClass and AbstractInterface?

new Test1("JEFFFFFF") , new Test2("Hey , say something"), new Test4("Helen") , new Test3("Hey , say my name") are all instantiating concrete classes, not abstract ones.

If you refer to AbstractClass[] abstractclass_list = as proof of instantiating abstract classes, that is wrong. Here, you declare an array whose elements are of type AbstractClass, and Test1 and Test2 are (since they extend AbstractClass).

UPDATE

You could have something like this AbstractClass abs = new Test1("hey"); and what it does is it creates a new instance of class Test1, and references that instance from variable abs. abs's concrete type is Test1, but only methods declared in AbstractClass are visible on it. If you want to call methods of Test1, you would have to cast 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)
like image 91
Predrag Maric Avatar answered Jan 20 '26 04:01

Predrag Maric



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!