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 literalRectangle.Class
,但这检查一个小事实,并且总是正确的
- 若要修复此错误,您定义了一个变量
Class Rectangle
,但此变量与Rectangle
类没有任何关系,除非用Class literalRectangle.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");
}