如何检查抽象对象的实例是否属于特定的子类

时间:2019-06-04 19:33:03

标签: java object inheritance instance abstract-class

我在这里引用了这个重复的问题:
Check if a Class Object is subclass of another Class Object in Java

我有一个名为“ Figure”的抽象父类,其中有两个子类“ Circle”和“ Rectangle”,这两个子类都扩展了该抽象父类。我试图确定一个Figure对象是否为Circle类型或Rectangle类型。

我的原始代码是:

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

     return isInstance;
  }

研究完上面的链接问题后,我将代码重写如下:

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

由于某种原因,除非我在主类中添加以下内容,否则这将无法工作:

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

我不确定将其包含在我的类中的重要性,如果没有,似乎需要将其作为参数包含在我的方法中。我无法正确调用和测试此方法,因为我不确定在调用时要向该方法传递什么参数。我想写类似的东西:

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

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

其中'shape1'是一个图形对象,已实例化为圆形或矩形。因为参数的类型是Figure,所以我不确定如何定义'isRectangle'方法来获取Figure对象(抽象父对象)并具体确定其实例是哪个子类。或者最好不带任何参数,而只是通过使用Figure对象调用该方法来完成工作。我有点困惑如何继续。

*编辑:根据用户的建议,我重写了以下,由于在两种情况下输出均为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;
}

5 个答案:

答案 0 :(得分:2)

这将始终返回false,因为Figure Class实例不是Rectangle Class实例的子类:

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

您通常希望在不知道运行时类型的变量的类上调用isAssignableFrom()
会更有意义:

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

这可以知道figure变量 IS 的类的实例是否为Rectangle

引入一种处理需求的方法将更加有意义,因为它是动态的,并且还允许处理不同的类兼容性检查:

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

您可以这样使用它,例如:

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

显示:

  

true

     

false

     

false

当然,所有这些都将以true的形式输出FigureCircleRectangleFigure

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

答案 1 :(得分:2)

您可以使用.getClas()方法找到子类

    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");
    }

答案 2 :(得分:1)

我没有太多理由将您的代码与可分配的代码复杂化。您的原始代码有效。除此之外,检查变量的类不是一个好习惯,请尝试重组代码。 (检查多态性,Barbara Liskov原理和界面分离原理) 为了澄清问题:图形不是对象,因为它是抽象的,而是类型。类型是变量声明左侧的内容。

答案 3 :(得分:1)

在我们获得Java模式匹配之前,您的原始实现是正确且最简单的实现。

更详细的解释:

instanceof运算符可用于检查对象是否为特定类的实例。这符合您的意图。

您可以使用ClassA.isAssignableFrom(ClassB)实现类似的功能。在这里,ClassA是超类,ClassB是子类。请注意,此函数将两个类(Class<?>的实例)进行比较,而不是将实例与一个类进行比较。

您可以使用getClass方法从实例中获取类,因此,结果代码如下所示:

Rectange.class.isAssignableFrom(figure.getClass())

您建议的支票

Figure.class.isAssignableFrom(Rectangle);

有多个问题:

  • 语法错误:您需要在右侧使用Class<?>实例,可以使用类文字Rectangle.class,但这可以检查一个琐碎的事实,并且始终为真。
  • 为解决此错误,您定义了一个变量Class<?> Rectangle,但该变量与Rectangle类没有任何关系,除非已使用类文字Rectangle.class显式初始化了该变量
  • 您不在任何地方使用图实例

答案 4 :(得分:1)

我将在这里进行提示,并指出以下方法中的错误:


public static boolean isInstanceOfRectangle(Figure figure)
{
    //boolean isInstance = figure instanceof Rectangle;
    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 Rectangle;
    boolean isInstance = figure instanceof Rectangle;
    if (isInstance == true)
        System.out.println("instance of circle!");
    else
        System.out.println("is NOT a circle");
    return isInstance;
}

在第二种方法中,您想要的行为是检查它是否为圆形。但是,您要检查它是否为矩形。

您应该检查figure instanceof Rectangle而不是figure instanceof Circle

PS。可以使用instanceof。还有什么是过分的了。