Search code examples
javaswingawtgraphics2ddowncast

Downcasting a Graphics instance - Why is it allowed?


I'm trying to figure out why it is allowed to downcast a Graphics instance to a Graphics2D instance.

It's usually against the rules to downcast a reference type that isn't inheriting the target type.

In the graphic-oriented classes the hierarchy is like the following:

  1. Graphics is the superclass
  2. Graphics2D is the subclass of the superclass Graphics

When drawing something in Swing you override the paint() method - And if you're in need of 2D-drawing you downcast the automatically supplied Graphics instance from the paint() method to a Graphics2D instance:

public void paint(Graphics g)
{
    super.paint(g);

    Graphics2D g2d = (Graphics2D)g;
}

But this is reverse? A Graphics instance is NOT inheriting a graphics2D instance - It's the Graphics2D instance that IS inheriting a Graphics instance when looking at the class-hierarchy!

Why is this allowed?


Solution

  • Graphics2D is a class which inherits from Graphics - the same way that "human" is a class of "biped", and it is true that all humans are bipeds but it is not true that all bipeds are humans.

    java.awt.Graphics dates to the earliest days of Java and was not very sophisticated. Waphen Swing and Java2D were created, Graphics2D was created as a subclass of Graphics so that old code would work - backwards compatibility was a religion at Sun (and not a bad one).

    JComponent and other Swing classes inherit from java.awt.Component, which used the old API. To make it easy for people to migrate from AWT to Swing without making any changes except the superclass, Swing kept the signature of taking a Graphics rather than a Graphics2D.

    It is well documented that in Swing, the Graphics passed to paint(Graphics) will always be a Graphics2D, so you do not need an alternate code-path to handle the case that it is not.