Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查超类中的对象中是否存在成员变量?_Java_Inheritance - Fatal编程技术网

Java 检查超类中的对象中是否存在成员变量?

Java 检查超类中的对象中是否存在成员变量?,java,inheritance,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 { Sub

我的类是这样定义的

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的不同对象,因为我希望这两个类的对象相互作用,而且我实际上有四个子类(例如,我这里只使用了两个子类),所以我想把它们都放在一个数组中。我用了下面的东西

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

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

另一种允许您提供上下文相关默认值的解决方案使用
可选

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

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

假设
Property
something
字段具有此getter(否则您可以使用
p->p.something
而不是
Property::getSomething
)。

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

另一种允许您提供上下文相关默认值的解决方案使用
可选

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

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

假设
Property
something
字段具有此getter(否则您可以使用
p->p.something
而不是
Property::getSomething
)。

编译将不允许您访问
prop
,因为就编译所知,
superObj
是超类的实例,而不是子类的实例

我认为您最好只检查SubOne的
instanceof
并删除
hasProperty
标志

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

编译不允许您访问
prop
,因为就编译所知,
superObj
是超类的实例,而不是子类的实例

我认为您最好只检查SubOne的
instanceof
并删除
hasProperty
标志

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

一种解决方案是在超类中有一个名为
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");

与模板方法相比,这种方法的优点是它适用于属性的任何应用程序,而无需更改。

一种解决方案是在超类中有一个名为
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");

与模板方法相比,这种方法的优点是它适用于属性的任何应用程序,而无需进行更改。

您是否尝试将
superObj
强制转换为
SubOne
?@RamenChef我这么认为,但我将所有SubOne和SubTwo类型的对象存储在单个数组中。那么,我如何知道是将其转换为SubOne还是SubTwo呢?取决于
hasProperty
是否为真。您还可以使用
instanceof
关键字。我还发布了另一个解决方案作为答案。您是否尝试将
superObj
强制转换为
SubOne
?@RamenChef我这么认为,但我将所有SubOne和SubTwo类型的对象存储在单个数组中。那么,我如何知道是将其转换为SubOne还是SubTwo呢?取决于
hasProperty
是否为真。您还可以使用
instanceof
关键字。我还发布了另一个解决方案作为答案。我认为这种方法比其他答案更好。它更像java,而不是JavaScript。这意味着更安全,如果发生错误,更容易发现。我认为这种方法比其他方法更好。它更像java,而不是JavaScript。这意味着更安全,如果发生错误,更容易发现。