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?

+3


source to share


5 answers


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)

      

+3


source


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.

+1


source


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.

+1


source


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 .... !!!

+1


source


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).

0


source







All Articles