Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to check if an instance of an abstract object belongs to a particular subclass

I am referencing this duplicate question here:
Check if a Class Object is subclass of another Class Object in Java

I have an abstract parent class named 'Figure' of which I have two subclasses, 'Circle' and 'Rectangle' both of which extend this abstract parent. I am trying to determine if a Figure object is of type Circle or type Rectangle.

My original code was:

 public boolean isInstanceOfRectangle(Figure figure)
 {
     boolean isInstance = figure instanceof Rectangle;
     System.out.println("instance of rectangle!");

     return isInstance;
  }

After studying the linked question above, I have rewritten my code as follows:

public boolean isRectangle()
{
    boolean isInstance = Figure.class.isAssignableFrom(Rectangle); 
    System.out.println("instance of rectangle!");
    return isInstance;  
 }

For some reason this does not work unless I include the following in my main class:

public Class<?> Rectangle;
public Class<?> Circle1;

I'm not sure the significance of including this in my class, if I do not, it seems to require that I include it as a parameter in my method. I am unable to correctly invoke and test this method because I am unsure what parameter to pass into the method when invoked. I'd like to write something like:

public void mouseReleased(MouseEvent e)
{
    if ((isRectangle(shape1)))
    addRectangle((Rectangle)shape1, e.getComponent().getForeground());

    else if ((isCircle(shape1)))
    addCircle((Circle) shape1, e.getComponent().getForeground());   
 }

where 'shape1' is a Figure object that was instantiated as either a circle or a rectangle. Because the parameter is of type Figure, I am unsure how to define the 'isRectangle' method to take a Figure object (the abstract parent) and determine specifically which subclass it is an instance of. Or preferrably to take no parameter and just do the work by using the Figure object to invoke the method. I am a bit confused how to proceed.

*Edit: upon user suggestions, I have rewritten the following which does NOT appear to work because in both cases the output is FALSE.

Figure circleObj = new Circle(Color.BLUE);

System.out.println(isInstanceOfRectangle(circleObj));
System.out.println(isInstanceOfCircle(circleObj));

public static boolean isInstanceOfRectangle(Figure figure)
{
    boolean isInstance = figure instanceof Rectangle;
    if (isInstance == true)
        System.out.println("instance of rectangle!");
    else
        System.out.println("is NOT a rectangle");
    return isInstance;
}


public static boolean isInstanceOfCircle(Figure figure)
{
    boolean isInstance = figure instanceof Circle;
    if (isInstance == true)
        System.out.println("instance of circle!");
    else
        System.out.println("is NOT a circle");
    return isInstance;
}
like image 880
Trixie the Cat Avatar asked Dec 31 '22 22:12

Trixie the Cat


2 Answers

That will always return false since the Figure Class instance is not a subclass of the Rectangle Class instance :

boolean isInstance = Figure.class.isAssignableFrom(Rectangle.class); 

You want to generally invoke isAssignableFrom() on the class of a variable which you don't know the runtime type.
It would make more sense :

Figure figure = ...;
boolean isInstance = Rectangle.class.isAssignableFrom(figure.getClass()); 

That allows to know whether the instance of the class of the figure variable IS a Rectangle.

Introducing a method to handle the requirement would make still more sense as it is dynamic and it also allows to handle different class compatibility checks :

  public static boolean isInstanceOf(Figure figure, Class<?> clazz){
    boolean isInstance = clazz.isAssignableFrom(figure.getClass());
    return isInstance;
  }

And you could so use it such as :

System.out.println(isInstanceOf(new Rectangle(), Rectangle.class));    
System.out.println(isInstanceOf(new Circle(), Rectangle.class));    
System.out.println(isInstanceOf(new Figure(), Rectangle.class));    

That prints :

true

false

false

And of course all of these will outputtrue as a Figure, a Circle and a Rectangle are Figures :

System.out.println(isInstanceOf(new Rectangle(), Figure.class));    
System.out.println(isInstanceOf(new Circle(), Figure.class));    
System.out.println(isInstanceOf(new Figure(), Figure.class));    
like image 89
davidxxx Avatar answered Jan 08 '23 01:01

davidxxx


You can use the .getClas() method to find the subclass

    Rectangle aRectangle = new Rectangle();
    if (aRectangle.getClass == Rectangle.class){
        // Do what you would do if it was a rectangle
        System.out.println("you have a rectangle");
    }   
    else{
        // The figure is not a rectangle 
        System.out.println("the figure is not a rectangle");
    }
like image 38
Joe Giusti Avatar answered Jan 08 '23 01:01

Joe Giusti