Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to instantiate abstract class using anonymous inner class and mechanism to access method within it [duplicate]

There is no any way to create object using abstract class. But when using anonymous inner class it is possible to run the following code. And not only that start() method is not accessible, therefore What is the reason for running following program without giving any compile error and what is the mechanism to access start() method.

abstract class Vehicle{
        abstract void park();
    }   

    class Demo{
        public static void main(String args[]){
            Vehicle v1=new Vehicle(){
                int speed;
                void park(){
                    System.out.println("Parking for cars...");
                }
                void start(){
                    System.out.println("Start...");
                }
            };
            v1.park();
        }
    }
like image 809
Saveendra Ekanayake Avatar asked Sep 05 '15 06:09

Saveendra Ekanayake


2 Answers

Consider the following piece of code (code 2).

abstract class Vehicle{
    abstract void park();
}   

class Demo{
  static class Car extends Vehicle {
       int speed;
       void park(){
                System.out.println("Parking for cars...");
       }
   }

   public static void main(String args[]){
        Vehicle v1=new Car();
        v1.park();
   }
}

It is no surprise that the previous piece of code gives no compiler error.
Car extends Vehicle and Car is not abstract. Hence you can instantiate it.

Lets see what happens when code 2 is compiled :

javac *.java
list .class files
Demo$Car.class  Demo.class  Vehicle.class

And this is what happens when the code in the question (code 1) is compiled :

javac *.java
list .class files
Demo$1.class  Demo.class  Vehicle.class

We get the same except we get Demo$1.class in code 1 and Demo$Car.class in code 2.
That happens because code 1 is actually creating a class which inherits from Vehicle. A so called anonymous class. The class has no name(*) but it is still a full fledged class which inherits from Vehicle and can be instantiated just as Car can be instantiated.

This code :

Vehicle v1=new Vehicle(){

is NOT instantiating an object of class Vehicle. It is instantiating an object of a class which inherits from Vehicle which has no name.

(*) Actually it does have a name. Its name is "1 in Demo" aka Demo$1. The JVM needs a name to be able to run it, you can't just tell the JVM to run something without telling it what to run. The name is one which is not a sintactically valid name for a class; can't name a class as 1. This is by dessign as it ensures that annonymous class names won't clash with normal class names.

like image 158
Anonymous Coward Avatar answered Sep 29 '22 07:09

Anonymous Coward


this is exactly the idea in abstract classes. you can't instanciate the abstract class, but you can instanciate any sub-class of it that implements the abstract methods. Such sub classes can be concrete classes, or anonymous classes like you did here, so no reason for this code not to compile

like image 28
Nir Levy Avatar answered Sep 29 '22 07:09

Nir Levy