代码之家  ›  专栏  ›  技术社区  ›  AlbertoPL

实例与类型铸造技术

  •  2
  • AlbertoPL  · 技术社区  · 16 年前

    在超类-子类结构之外 它采用a型(因此能够处理所有B、C和D)。

    在Java中,我使用instanceof来检索真正的类型,但是我最终不得不对真正的类型进行大量的转换,这看起来很混乱。有人对如何使代码更干净有什么建议吗?

    感谢所有回答的人,非常感谢!

    编辑: 我用斜体字补充了进一步的澄清。谢谢

    4 回复  |  直到 16 年前
        1
  •  3
  •   MattC    16 年前

    如果需要检查类型,我不理解为什么要让它们从基类继承。抽象类/接口A定义了一系列B、C和D应该实现的函数,然后取A实例的函数应该只调用这些抽象函数。如果您需要调用一个只包含B的函数(因此不会被重写),那么您的函数应该采用B的实例,而不是a的实例。

    还是我完全没有抓住重点?我今天早上没有喝咖啡因。

        2
  •  3
  •   Yishai    16 年前

    泛型是用来处理这个问题的。

    考虑下面的例子:

    public class SuperClass<T extends SuperClass> {
    
         public abstract void someMethod(T param);
    
    }
    
    
    public class SubClassA extends SuperClass<SubClassA> {
    
        public void someMethod(SubClassA param) {}
    }
    

    如果这是您所需要的,您可以简单地通过方法重载来实现这一点。考虑:

      public void someMethod(SuperClass param) {
          if (param instanceof SubClassA) {
             someMethod((SubClassA) param);
          } else if (param instanceof SubClassB) {
             someMethod((SubClassB) param);
          }
      }
    
      public void someMethod(SubClassA param) {}
    
      public void someMethod(SubClassB param) {}
    

    但这并没有让你走出if的陷阱。这取决于有多少人和他们有多不稳定,看一个更重的解决方案是否值得在这里。

        3
  •  0
  •   oxbow_lakes    16 年前

    听起来好像你想要这个 . 就我个人而言,我不是一个超级粉丝,但它的工作原理如下:

    class A { abstract void visit(MyVisitor visitor); }
    

    这必须在每个子类中实现:

    class B extends A { 
        public void visit(MyVisitor v) { v.visit(this); }
    }
    

    因此,实际访问者使用重载,如下所示:

    interface MyVisitor {
       public void visit(B b);
       public void visit(C c);
    }
    

    现在您可以实现访问者和调用 visit 针对您的A实例。然后将调用正确的回调方法:

    A a = new B();
    a.visit(this);
    

    假设 this 实例实现 MyVisitor ,这将导致在 visit(B)

        4
  •  0
  •   wax    16 年前

    正如易海所说,它看起来像一种设计气息。若您有instanceof-s,它会修改方法的行为,那个么您就走错了路。考虑将此行为移动到类的继承器中。

    此外,还可以使用泛型对类进行参数化。下面是一个代码示例

    abstract class A<T extends A>{
       abstract protected void someMethod(T value);
    }
    
    class B extends A<B>{
        protected void someMethod(B value) {
        }
    }
    
    class C extends A<C>{
        protected void someMethod(C value) {
        }
    }