【问题标题】:Checking if extended class is instance of interface检查扩展类是否是接口的实例
【发布时间】:2014-08-10 23:33:37
【问题描述】:

我正在尝试检查扩展类 B 的类 A 是否是某个接口的实例。

基本上这是我的设置:

public class House
{
    (variables)

    public House(variables) {...}
}

public class Kitchen extends House implements IFurniture
{
    (variables)

    public Kitchen(variables)
    {
        super(variables);
    }
}

public class Bathroom extends House implements IWalls

等等……

而且我有一个方法,我可以得到一个铸造的、家庭版的厨房和浴室。 我基本上想这样做:

public boolean hasFurniture(House house)
{
    if (house instanceof IFurniture){return true;}
}

我是否需要使用 house.getClass().getInterfaces() 并且考虑到参数已被强制转换,这是否可行?

问题是我正在为游戏编写模组,但我无法编辑游戏类。在这种情况下,只能编辑 Kitchen、Bathroom 和 hasFurniture。

也忽略我的类名,它们只是示例名称,以免您不小心混淆类。

【问题讨论】:

  • 您的hasFurniture 方法有什么问题?它应该可以工作。
  • 顺便说一句,您的类层次结构没有多大意义。厨房不是房子。浴室不是房子。它们不应该是 House 的子类。它们可能应该是 Room 的子类,而 House 应该包含房间的集合。
  • Eran,我的 IDE 说不能将 House 转换为 IFurniture,当然我的类层次结构没有多大意义,这不是重点。重点是展示我当前的设置。

标签: java interface casting


【解决方案1】:

您正在浪费多态性的好处。您不想使用带有instanceof 的接口来检查对象是否具有属性。 implementsextends 表示 IS-A,而不是 HAS-A。你显然想要后者。改为这样做:

public interface IFurniture {
    public boolean hasFurniture();
}


public class House implements IFurniture
{
    (variables)

    public House(variables) {...}

    @Override
    public boolean hasFurniture() {
        return false;
    }
}

public class Kitchen extends House
{
    (variables)

    public Kitchen(variables)
    {
        super(variables);
    }

    @Override
    public boolean hasFurniture() {
        return true;
    }
}

编辑:另外,Eran 正确地指出,这种层次结构一开始并没有多大意义——但这是一个更大的问题。

【讨论】:

  • 是的,我知道,但问题是我正在为游戏编写模组并且无法编辑游戏类。在这种情况下,只能编辑 Kitchen、Bathroom 和 hasFurniture。我现在要把它添加到问题中。
【解决方案2】:

让我们使用更易于理解的类层次结构。 您正在考虑这样的 instanceof 问题:

public class Person{

    public void die(){
        System.out.println(this + " died");
    }

    public void pushOffCliff(){
        if(this instanceof Flyable)
            Flyable f = (Flyable)this;
            f.fly();
        else
            die();
    }
}

public interface Flyable{

    public void fly();
}

public class Superhero extends Person implements Flyable{

    public void fly(){
        System.out.println("Up, up, and away!");
    }
}

当像 Patrick 在他的回答中那样使用类扩展和覆盖系统更有意义时,如下所示。人(真的只是人而不是超级英雄)不会飞。当被推下悬崖时,他们应该死。所以 person 类不应该处理“如果我不是一个真正的人,我实际上是一个......”的可能性;让子类来处理。

public class Person{

    public void die(){
        System.out.println(this + " died");
    }

    public void pushOffCliff(){
        die();
    }
}

public interface Flyable{

    public void fly();
}

public class Superhero extends Person implements Flyable{

    public void fly(){
        System.out.println("Up, up, and away!");
    }

    @Override
    public void pushOffCliff(){
        fly();
    }
}

【讨论】:

    【解决方案3】:

    感谢 Eran,我刚刚解决了。

    我的问题是我投射了错误的元素。 在这种情况下,我正在投射 ItemStack(带有附加数据的项目)而不是 Item。 通过仅添加 .getItem() 我希望可以解决问题。

    感谢您的帮助,祝您有美好的一天!

    【讨论】:

      猜你喜欢
      • 2010-09-21
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2018-10-19
      • 2016-09-29
      相关资源
      最近更新 更多