Java 在设计上避免了instanceof

标签 java inheritance polymorphism

考虑以下类设计:

public class SuperType { };
public class SubType1 extends SuperType { };
public class SubType2 extends SuperType { };
public class SubType3 extends SuperType { };

public class Tuple {
    SuperType t1;
    SuperType t2;

    public Tuple(SuperType t1, SuperType t2) {
        this.t1 = t1;
        this.t2 = t2;
    }

    public void DoSomething1() {
        if((t1 instanceof SubType1) && (t2 instanceof SubType3))
            switch(t1, t2);
        else if((t1 instanceof SubType2) && (t2 instanceof SubType1)) 
             t1.DoSomething();
        else if( ... ) {
             t1.DoSomething();
             t2.DoSomething();
        }
        else if( ... )
            // ...
    }

    public void DoSomething2() {
        // basically the same
    }
}

由于操作依赖于两种类型,因此我无法通过将方法移至子类型来避免使用instanceof 运算符。有没有办法改进我的设计,从而避免使用instanceof?

我知道这里有很多类似的问题,但我想避免使用访问者,因为我有大约 20 个 DoSomething() 方法,这将导致 Visit() 的 9*20 实现。

最佳答案

在面向对象语言中执行此操作的正确方法是使用称为“双重调度”的模式(Googlable,但维基百科的页面不太好)。

“append”方法就是一个很好的例子:

class Super
{
    abstract void appendTo(Super target);
    abstract void append(Sub1 source);
    abstract void append(Sub2 source);
}

class Sub1
{
    void appendTo(Super target)
    {
        target->append(this); //calls the Sub1 overload
    }
    void append(Sub1 source)
    {
        ... this is Sub1, source is Sub1 ...
    }
    void append(Sub2 source)
    {
        ... this is Sub1, source is Sub2 ...
    }
}
class Sub2
{
    void appendTo(Super target)
    {
        target->append(this); //calls the Sub2 overload
    }
    void append(Sub1 source)
    {
        ... this is Sub2, source is Sub1 ...
    }
    void append(Sub2 source)
    {
        ... this is Sub2, source is Sub2 ...
    }
}

关于Java 在设计上避免了instanceof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33463495/

相关文章:

java - 如何使用 Java 将 Unicode 文本文件转换为 ANSI 格式

python - 在python中调用不同的方法

c++ - C++中的数据继承

c++ - 在 C++ 中,我们如何在不使用友元函数的情况下通过对象调用私有(private)函数?

c# - 我什么时候真正需要使用抽象方法?

java - JSON解析错误: Cannot deserialize instance of `` out of START_ARRAY token

java - 排序ArrayList : Comparison method violates its general contract

java - 如何从Java中的String中获取多个子字符串和额外的数字?

c++ - C++中的接口(interface)继承

java - 我应该使用父类(super class)的 setter 从子类初始化其实例变量吗?