我的课程以这样的方式定义
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");
}
答案 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);
}
假设Property
有something
字段的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");
这比模板方法的优势在于它适用于属性的任何应用程序而无需更改。