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

Java 如何检查抽象对象的实例是否属于特定的子类,java,object,inheritance,instance,abstract-class,Java,Object,Inheritance,Instance,Abstract Class,我在这里引用了这个重复的问题: 我有一个名为“Figure”的抽象父类,其中有两个子类“Circle”和“Rectangle”,它们都扩展了这个抽象父类。我试图确定地物对象是圆形还是矩形 我最初的代码是: public boolean isInstanceOfRectangle(Figure figure) { boolean isInstance = figure instanceof Rectangle; System.out.println("instance o

我在这里引用了这个重复的问题:

我有一个名为“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;
其中“shape1”是一个被实例化为圆形或矩形的地物对象。因为参数的类型是Figure,我不确定如何定义“isRectangle”方法来获取Figure对象(抽象父对象)并具体确定它是哪个子类的实例。或者更倾向于不带参数,只通过使用Figure对象调用方法来完成工作。我有点搞不清楚如何进行

*编辑:根据用户的建议,我重写了以下内容,但似乎不起作用,因为在这两种情况下,输出都是错误的


这将始终返回
false
,因为
实例不是
矩形
实例的子类:

boolean isInstance = Figure.class.isAssignableFrom(Rectangle.class); 
您通常希望对不知道运行时类型的变量类调用
isAssignableFrom()

这将更有意义:

Figure figure = ...;
boolean isInstance = Rectangle.class.isAssignableFrom(figure.getClass()); 
这样就可以知道
figure
变量类的实例是否为
矩形

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

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

真的

假的

假的

当然,所有这些都将输出
true
,作为
图形
圆形
矩形
图形
s:

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

我看不出有什么理由用assignable使代码复杂化。您的原始代码可以正常工作。除此之外,检查变量的类不是一个好的做法,请尝试重新构造代码。(检查多态性、Barbara Liskov原则和接口隔离原则)
为了澄清问题:图形不是一个对象,因为它是抽象的,它是类型。该类型位于变量声明的左侧。

在Java中实现模式匹配之前,您最初的实现是正确的,也是最简单的

更详细的解释:

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

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

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

Rectange.class.isAssignableFrom(figure.getClass())
你的支票

Figure.class.isAssignableFrom(Rectangle);
存在多个问题:

  • 语法错误:在右侧需要一个
    Class
    实例,可以使用Class literal
    Rectangle.Class
    ,但这检查一个小事实,并且总是正确的
  • 若要修复此错误,您定义了一个变量
    Class Rectangle
    ,但此变量与
    Rectangle
    类没有任何关系,除非用Class literal
    Rectangle.Class显式初始化
  • 在任何地方都不使用图形实例

我将在此插话并指出这些方法中的一个缺陷:


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;
}
在第二种方法中,您希望它的行为是检查它是否是圆。而是检查它是否为矩形

您应该检查圆形的图形实例,而不是矩形的图形实例

另外,可以使用
instanceof
。其他任何东西都是多余的。

您可以使用.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");
    }

您几乎应该总是重新构造代码以避免需要这样做。这两种情况都是错误的,因为您在这两种方法中都检查了矩形的
图形实例。您应该检查第二个圆中的
图instanceof Circle
。正如@chrylis所提到的,您应该以这样的方式重新构造代码,以避免此类检查。一个选项是在Figure中创建一个抽象方法,并在Circle/Rectangle类中重写它以实现所需的行为。此外,如果您知道要检查的类是可从
中指定的,编写
图instanceof Rectangle
可能更容易。我听说最初的实现是可行的,但当我尝试实例化一个圆形对象时,我发现圆形和矩形类型都为false。您在IsInstanceof circle方法中再次测试矩形
Figure.class.isAssignableFrom(Rectangle);

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