2

This works good.

package abstracttest;

public abstract class AbstractClass implements NewInter {

    public abstract void doStuff();

    public void doStuff2() {
        System.out.println("in doStuff2");
    }

    /*
     * public static void main(String a[]) { AbstractClass ab = new
     * AbstractClass() {
     * 
     * @Override public void doStuff() { // TODO Auto-generated method stub
     * System.out.println(" doStuff "); }
     * 
     * @Override public void doInter() { // TODO Auto-generated method stub
     * 
     * } };
     * 
     * ab.doStuff2(); ab.doStuff();
     * 
     * NewInter ni = new NewInter() {
     * 
     * @Override public void doInter() { // TODO Auto-generated method stub
     * System.out.println("do Inter"); }
     * 
     * }; ni.doInter();
     * 
     * AbstractClass ab1 = new AbstractClass(); }
     */

}

interface NewInter {

    String con = "Hell";

    void doInter();
}

class Impl extends AbstractClass {

    @Override
    public void doInter() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doStuff() {
        // TODO Auto-generated method stub

    }

    public static void main(String[] s) {
        AbstractClass ab = new AbstractClass() {

            @Override
            public void doInter() { // TODO Auto-generated method stub
                System.out.println("impl doInter");
            }

            @Override
            public void doStuff() { // TODO Auto-generated method stub
                System.out.println("impl doStuff");
            }

        };
        ab.doInter();
        ab.doStuff();

        NewInter ni1 = new NewInter() {

            @Override
            public void doInter() {
                // TODO Auto-generated method stub

            }
        };
        ni1.doInter();
    }

}

I was able to instantiate the abstract class and interface both from within the abstract class' main() and from the class Impl.
How is this possible?
I was expecting an exception but the invocation worked correctly.
Can someone please explain the phenomena? I am confused.

A Java abstract class also cannot be instantiated, but can be invoked if a main() exists.

I read this in a blog. What does it mean?

And is there any other way of invoking the constructor of an abstract class? Please let me know if there is.

Freakyuser
  • 2,774
  • 17
  • 45
  • 72

2 Answers2

14

No, you didn't instantiate them. You have only created anonymous classes that implement the interface or extend the abstract class. Objects of these anonymous classes types are actually instantiated.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • That is a wonderful explanation. Now I understand that we are subclassing the abstract class and not creating an instance. But can you please explain about this point **A Java abstract class also cannot be instantiated, but can be invoked if a main() exists.** I have already mentioned it in the question. – Freakyuser Feb 20 '13 at 09:53
  • You are building some instances of anonymous class type and call their methods. You can do this inside main or inside any other method. – Dan D. Feb 20 '13 at 09:56
  • So you mean to say that ** A Java abstract class also cannot be instantiated, but can be invoked if a main() exists**, this means it can be invoked using anonymous inner class and not through some other way? – Freakyuser Feb 20 '13 at 10:05
  • Once you have a reference to it, you can invoke its methods. – Dan D. Feb 20 '13 at 10:06
  • I meant invoking its constructor not its methods – Freakyuser Feb 20 '13 at 10:11
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24818/discussion-between-freakyuser-and-dan) – Freakyuser Feb 20 '13 at 10:12
  • A constructor of a class is invoked either directly, which in the abstract classes is not possible or by a constructor of a subclass. – Dan D. Feb 20 '13 at 10:13
8

If I do this:

new AbstractClass() {
   public void methodToImplement() {
   }
}

it's creating an anonymous class derived from the abstract class. It's so called (anonymous) since the class definition doesn't have it's own accessible name and you can't access the definition again. The definition/instantiation occur together e.g.

AbstractClass ac = new AbstractClass() {
   ...
}

(it's a subclass of AbstractClass)

Note that you can do this for both interfaces and abstract classes, but you'll have to implement the required methods appropriately.

The above is often used to implement simple interfaces/abstract classes in a concise form, often as inner classes within callbacks. See this SO question for more info, and the Nested Class tutorial for more discussion.

Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • 1
    Thank you for the explanation. Can you please explain **A Java abstract class cannot be instantiated, but can be invoked if a main() exists**; the 7th point, in the [blog](http://javapapers.com/core-java/abstract-and-interface-core-java-2/difference-between-a-java-interface-and-a-java-abstract-class/)? – Freakyuser Feb 21 '13 at 09:05
  • 2
    I think it means that you can have a *static* main() method and thus run com.example.AbstractClass from the command line. Note that's *not* instantiating an instance of the class, since the main method is static – Brian Agnew Feb 21 '13 at 10:33