2016-08-28 3 views
0

私のクラスは、私は両方のクラスのオブジェクトが他の一人一人と対話し、また、実際にIしたいので、私は、1つのアレイ内のSubOneとSubTwoの異なるオブジェクトを必要とこのsuperClassのオブジェクトにメンバー変数が存在するかどうかを確認しますか?

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

のような方法で定義されています4つのサブクラスを持っています(例えばここでは2つだけを取りました)ので、それらをすべて単一のArrayに入れたいと思っていました。私は次のことを使用しました。

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

'SuperObj'を' SubOne'にキャストしようとしましたか? – RamenChef

+0

@RamenChef私はこれを考えましたが、すべてのSubOneおよびSubTwoタイプのオブジェクトを単一の配列に格納しています。それで、SubOneまたはSubTwoにキャストするかどうかはどのようにわかりますか? –

+0

'hasProperty'が真であるかどうかによって。 'instanceof'キーワードを使うこともできます。私は答えとして別の解決法を投稿しています。 – RamenChef

答えて

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

テンプレートメソッドに対するこのことの利点は、それがあることを必要とせずにプロパティの任意のアプリケーションのために働くということであるので、同様かわった。

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

次にように使用:Propertyは(そうでなければ、代わりにProperty::getSomethingp -> p.somethingを使用することができます)somethingフィールドに、このゲッターを持っていると仮定すると、

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

    System.out.print(value); 
} 

1

コンパイルでは、superObjがインスタンスのSubOneではなく、superObjがインスタンスであるため、propにアクセスすることはできません。

instanceof SubOneをチェックして、hasPropertyフラグを削除する方が良いと思います。

+0

私はこの方法が他の答えより優れていると思います。それはより多くのJavaのような、JavaScriptのようなものです。つまり、より安全であることを意味し、エラーが発生した場合は、見つけやすくなります。 –

関連する問題