Search code examples
javaawtgraphics2d

How are abstract classes instantiated in Java?


I was reading Head First Java and it mentioned the following:

The argument to paintComponent() is declared as type Graphics (java.awt.Graphics).
public void paintComponent(Graphics g) { }

So the parameter 'g' IS-A Graphics object. Which means it could be a subclass of Graphics (because of polymorphism). And in fact, it is.

The object refrenced by the 'g' parameter is actually an instance of the Graphics2D class

Now I wanted to check a few methods of Graphics2D class, so I opened the Oracle documentation and searched for the class. I found what I wanted, but then I saw that Graphics2D is an abstract class. Now Head First mentions that the parameter 'g' is actually an instance of the Graphics2D class. Now I clearly know that we cannot instantiate an abstract class, but we can create a concrete subclass out of it or even an anonymous class.

Now I don't want to shoot in the dark and want some evidence for at least java.awt.Graphics2D.

One possibility I can think of is something like this:

public abstract class GFG {
    public abstract void foo();
}

class ABC extends GFG {

    @Override
    public void foo() {
        System.out.println("Hey");
    }

    public static void main(String[] args) {
        GFG obj = new ABC();
        obj.foo();
    }
}

How exactly does happen and how are we able to instantiate the class Graphics2D?

I have also seen this piece of code:

@Override
public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D)g;
   ...
}

Which is only possible if g is an object like:

Graphics g = new Graphics2D();

Which is again not possible as Graphics2D is an abstract class.


Solution

  • What you've said in the first half of your question is correct. There must a concrete implementation of Graphics2D. You can't instantiate it directly as it's abstract.

    In regards to your second point, your assumption is wrong. For the call

    Graphics2D g2d = (Graphics2D) g;
    

    g must be a concrete subclass of Graphics2D, so when g was instantiated it would have been something like:

    Graphics g = new Graphics2DSubclass();
    

    The cast is only letting the compiler know that g is a Graphics2D, the same way that you could say a Dog is an Animal. There is no guarantee or mention of the specific implementation.