关于java中的向下转换的良好实践

时间:2014-06-03 20:07:21

标签: java

我有一套操作。每个操作都是两个步骤的序列。所以,我有一个执行这两个步骤的基类,所有操作都扩展了这个基类,并为这两个步骤提供了实际的实现。实施例

class Base {
    Step1 step1;
    Step2 step2;

    B execute() {
        A a = step1.perform();
        B b = step2.perform(a);
    }

    //Set methods...
}

这里Step1和Step2是接口,可以改变它们的实现来做不同的事情。

我有以下问题:

  • step2的每个实现都将A的实例作为输入,也可以包含派生类型的A.所以我需要做一个向下转换。在这种情况下是否可以做一个向下倾斜,或者有更好的方法来实现这个目标吗?
  • step2的某些实现可能不会返回任何值。如果我们只为类型层次结构有一个空类,而其他类扩展了这个类,那可以吗?

2 个答案:

答案 0 :(得分:1)

问题1

是的,没关系。扩展A类或实现接口A(A是什么)的每个类都将是“A的实例”。所以将它传递给需要A类对象的方法是完全可以的。没有什么可担心的。这是你应该如何使用接口和继承。同一个超级阶级有不同类型的“专业化”。

问题2

这是您的API设计问题。如果您希望此方法 可以返回null,则可以执行此操作。但你应该把它记录得很好!

Java 8中一种非常新的可能性是所谓的 Optionals 。如果方法可以返回null并且您希望强制程序员记住这一点,则可以使用它们。这将是最干净(和推荐)的方式。您可以在http://java.dzone.com/articles/optional-java-8-cheat-sheet找到示例和说明。基本上你会说类perform的方法Step2将返回一个Optional而不是类型:

interface Setp2 {
    public Optional<B> perform(A a);
}

// the optional will wrap the actual result which could be null
// since Java 8
Optional<B> b = step2.perform(a);

答案 1 :(得分:0)

听起来你应该使用泛型:

interface Step1<T extends A> {
    T perform(T a);
}
interface Step2<T extends A, U extends B> {
    U perform(T a);
}

class Base<T extends A, U extends B>>{
Step1<T> step1;
Step2<T, U> step2;

B execute() {
    T a = step1.perform();
    U b = step2.perform(a);
}

//Set methods...

}

关于返回“无”,最好的方法是返回null