从superClass检查对象中是否存在成员变量?

时间:2016-08-28 18:28:41

标签: java inheritance

我的课程以这样的方式定义

class SuperClass
{
  protected boolean hasProperty;
}

class SubOne extends SuperClass
{

  protected Property prop;   

  SubOne()
  {
    this.hasProperty=true;
    this.prop=new Property(); 
  }
}

class SubTwo extends SuperClass
{
  SubTwo()
  {
    this.hasProperty=false;
  }
}

我需要SubOne和SubTwo的不同对象在一个数组中,因为我希望两个类的对象与每个其他对象交互,而且我实际上有四个SubClasses(例如我在这里只采用了两个),所以我想将它们全部放在单个阵列中。我使用了以下内容。

SuperClass[] superClass={
  new SubOne(),
  new SubTwo()
}

现在,在迭代循环时,如果我写下面的内容,它会给我错误。我花时间寻找灵魂,但我找不到它。

for(Superclass superObj:superClass)
{
  if(superObj.hasProperty)
    System.out.print(superObj.prop.something);
    //when hasProperty is false, this statement should not be called, 
    //but compiler gives error
  else
    System.out.print("Something");
}

3 个答案:

答案 0 :(得分:1)

oop解决方案将使用模板方法,例如:

class SuperClass {
    protected void templateMethod(){
        System.out.print("Something");
    }
}

class SubOne extends SuperClass {

    protected Property prop;   

    SubOne() {
        this.hasProperty=true;
        this.prop=new Property(); 
    }

    @Override
    protected void templateMethod() {
        System.out.print(this.prop.something);
    }
}

class SubTwo extends SuperClass {...}

然后您的其他代码可以调用:

for(Superclass superObj : superClass) {
    superObj.templateMethod();
}

另一种允许您提供依赖于上下文的默认值的解决方案使用Optional

class SuperClass {
    protected Optional<Property> prop = Optional.empty();
}

class SubOne extends SuperClass {
    ...
    SubOne() {
        this.prop = Optional.of(new Property());
    }
    ...
}

然后使用:

for(Superclass superObj : superClass) {
    String value = superObj.prop
                       .map(Property::getSomething)
                       .orElse("Something");

    System.out.print(value);
}

假设Propertysomething字段的getter(否则您可以使用p -> p.something代替Property::getSomething)。

答案 1 :(得分:1)

编译不允许您访问prop因为编译知道,superObj是SuperClass的实例,而不是SubOne的实例。

我认为最好只检查instanceof SubOne并删除hasProperty标记。

    for (SuperClass superObj : superArray) {
        if (superObj instanceof SubOne) { // check instanceof
            System.out.println(((SubOne)superObj).prop.something); // cast
        }
        else {
            System.out.println("Something");
        }
    }

答案 2 :(得分:1)

一种解决方案是在超类中使用一个名为getProperty的方法,一旦验证了属性的存在,就可以从任何实例调用该方法。在超类中,该方法可以返回null或抛出异常;在子类中覆盖它以返回实际属性。像这样:

class SuperClass
{
    protected boolean hasProperty;

    protected Property getProperty()
    {
        throw new UnsupportedOperationException();
    }
}

class SubOne extends SuperClass
{
    protected Property prop;   

    SubOne()
    {
        this.hasProperty=true;
        this.prop=new Property(); 
    }

    @Override
    protected Property getProperty()
    {
        return prop;
    }
}

class SubTwo extends SuperClass
{
    SubTwo()
    {
        this.hasProperty=false;
    }
}

迭代的代码如下:

if (superObj.hasProperty)
    System.out.println(superObj.getProperty().something);
else
    System.out.println("Something");

这比模板方法的优势在于它适用于属性的任何应用程序而无需更改。