【问题标题】:Is it a good practice to provide check the instance type in the base class提供检查基类中的实例类型是否是一种好习惯
【发布时间】:2015-03-21 19:27:03
【问题描述】:

我有四门课。 A,B,D 是派生类,C 是基类。如果给定的实例是 A 或 D,则返回 true;否则,返回假。以下是我的代码:

 //A.java
 public class A extends C{
 }

 //B.java 
 public class B extends C {
 }

 //D.java
 public class D extends C {
 }

 //C.java
 public class C {
     public boolean isSupported(C object){
         boolean result= false;

         // Object type check
         if(object instanceof A || object instanceof D){ // A, D
            result=true;
          }
          else {  // B, C
            result=false;
          }
       return result;
    }

    public static void main(String args[]){
        C tmp = new A();
        System.out.println(tmp.isSupported());
     }
 }

那么在基类 C 的 isSupported() 中检查实例/对象类型是一个好习惯吗? (对于 C++,如果在不同的文件中定义了四个类,如果这样做,我必须在提供 C 类实现的文件中包含定义 A 类和 D 类的头文件,这有点奇怪)。

我知道我可以在每个派生类中提供一个覆盖函数。但它是不是有点重复代码,特别是如果我有很多派生类。

谁能给我一些建议?

谢谢

【问题讨论】:

  • 这个设计很糟糕。如果 B 不受“支持”,则 B 不应是 C 的基类。

标签: java c++


【解决方案1】:

您应该在子类中覆盖isSupported,以便AD 覆盖它以返回trueC 定义默认行为(返回false)和B 继承该默认行为来自C 没有覆盖。

public class C {
    public boolean isSupported() {
        return false;
    }
}

public class A extends C {
    @Override
    public boolean isSupported() {
        return true;
    }
}

public class B extends C {
    // inherits isSupported from C
}

public class D extends C {
    @Override
    public boolean isSupported() {
        return true;
    }
}

【讨论】:

  • 这或多或少是 JDK 使用 Collection 类处理这个问题的方式。例如,AbstractCollection,通过抛出 UnsupportedOperationException 来实现 clear 方法。支持该方法的派生类使用所需功能覆盖,不支持该方法的其他派生类采用基类的默认行为(抛出异常)。
  • 但是如果我有很多派生类,是否意味着我需要在每个派生类中定义一个覆盖函数?
  • 就我个人而言,我一直觉得通过你的接口提供一个方法,然后抛出一个 UnsupportedOperationException 非常臭。
  • @longli 不,您只在应该返回 true 的子类中覆盖 isSupported
【解决方案2】:

基类永远不需要知道关于扩展它的类的任何信息。否则,您需要在扩展基类时对其进行修改。我会认为这种风格非常糟糕(换句话说,它“闻起来”——不,这不是侮辱——参见“code smell”)。

为什么需要这样做?

【讨论】:

    猜你喜欢
    • 2017-02-20
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多