Enrico
Enrico

Reputation: 445

Is it allowed to extend the Shape class?

I have multiple geometries which extends from a Shape class like this:

public class ExtendedLine extends Line {

  private String attribute;

  // more attributes and methods
}
public class ExtendedCircle extends Circle {

  private String attribute;

  // more attributes and methods
}

Now, to access all geometries at once, I defined a super class which extends Shape and contains all attributes and methods which the ExtendedLine and ExtendedCircle have in common. This saves me a lot of redundant code.

public class Geometry extends Shape {
  
  private String attribute;
  
  // more attributes and methods
}
public class ExtendedLine extends Geometry {
}
public class ExtendedCircle extends Geometry {
}

Is it allowed / good practice to extend the Shape class?

Upvotes: 1

Views: 453

Answers (1)

Slaw
Slaw

Reputation: 46116

I assume you're talking about the javafx.scene.shape.Shape class. If that's correct, then the documentation1 says that you should not extend that class:

An application should not extend the Shape class directly. Doing so may lead to an UnsupportedOperationException being thrown.

However, the class is not final, it has a public constructor, and it has no package-private abstract methods (which you would not be able to override). So, there's nothing physically stopping you from extending Shape and compiling the code, but it may not work properly at run-time1. I would suggest you heed the documentation and don't extend it.

Note other classes have similar documentation (e.g., javafx.scene.Node)1. Likely these classes, if JavaFX were written today, would be sealed, with any extendable subclasses being marked non-sealed. See JEP 409: Sealed Classes.

There's another problem with extending Shape. When you extend Line then your subclass is a Line, just with the added attributes and methods. But when your e.g., ExtendedLine class extends Shape (via your Geometry class), then it is no longer a Line. You can't add it to your scene graph and expect a line to be drawn. That means either drawing the line yourself, or having the subclass wrap a Line instance that you can access; but in either case, what was the point of subclassing Shape in the first place then?


1. For all intents and purposes, you should interpret the documentation as if it said an UnsupportedOperationException will be thrown, not just may be thrown. I can only assume they worded it that way because the exception is only thrown when you add an instance of the direct subclass to the scene graph (at least in my tests), but not every application is guaranteed to attempt that.

I tested this with direct subclasses of javafx.scene.Node, javafx.scene.LightBase, javafx.scene.shape.Shape, and javafx.scene.shape.Shape3D. All of them resulted in an UnsupportedOperationException being thrown when added to the scene graph. There may be other classes with the same "problem", but those are the ones I'm aware of currently.

Upvotes: 6

Related Questions