Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用.getClass()是否被视为糟糕的设计?_Java_Oop - Fatal编程技术网

Java 使用.getClass()是否被视为糟糕的设计?

Java 使用.getClass()是否被视为糟糕的设计?,java,oop,Java,Oop,我目前正在实现一个函数,使用超类作为参数 例如: private void foo(Parent parent) { if(parent.getClass() == Child1.class) { Child1 c1 = (Child1) parent; System.out.println(c1.getChild1Attribute()); } else if(parent.getClass() == Child2.class) {

我目前正在实现一个函数,使用超类作为参数

例如:

private void foo(Parent parent) {
    if(parent.getClass() == Child1.class) {
        Child1 c1 = (Child1) parent;
        System.out.println(c1.getChild1Attribute());
    }
    else if(parent.getClass() == Child2.class) {
        Child2 c2 = (Child2) parent;
        System.out.println(c1.getChild2Attribute());
    }
    else if(parent.getClass() == Parent.class) {
        System.out.println(parent.getParentAttribute());
    }
}
这是个坏主意吗

我在这里读到一些帖子说,使用
getClass()
instanceof
是糟糕的设计:

    • 是的,这是一个糟糕的设计


      相反,您应该在超类中创建一个抽象方法,并在每个子类中重写它以执行所需的操作。

      这不一定是一个糟糕的设计,但它表明可能正在发生错误

      您的具体情况看起来很糟糕,因为一个方法似乎知道多个类。这可能表明您缺少过载的可能性,或者您没有机会使用多种调度模式之一:

      // Three overloads - one per target class
      private void foo(Parent obj) {
      }
      private void foo(Child1 obj) {
      }
      private void foo(Child2 obj) {
      }
      

      常见的多分派模式之一是,查看它是否适用于您正在解决的问题。

      首选
      实例的
      方法

      我支持instanceof方法的原因是,当您使用getClass方法时,您有一个限制,即对象仅等于同一类、同一运行时类型的其他对象


      是的,这是不良设计的标志。这就增加了在单个类中处理不同类的复杂性,而不是将相关知识封装在适当的类中。当您向层次结构中添加更多的类时,这会造成伤害,因为编译器不会提醒您为
      foo
      实现相关的新功能

      更好的版本是

      private void foo(Parent parent){
          System.out.println(parent.getFooParentAttribute());
      }
      

      然后在每个类上实现
      getFooParentAttribute

      您的方法存在两个问题。首先,假设您添加了一个子类
      Parent
      Child3
      。你的任何箱子都不包括这个,所以它根本不打印任何东西。如果您添加了一个新的子类
      Child1
      ChildOfChild1
      ,情况也是如此。这也不包括在内

      如果改用
      instanceof
      ,则
      ChildOfChild1
      将显示为
      Child1
      的实例,
      Child3
      将显示为
      Parent
      的实例

      但是一般来说,你想要完全避免这种模式的原因是,所有这些情况都是令人惊讶的。通常更好的方法是写作

      void foo(Parent p) {...}
      
      然后把一般代码放进去,然后对于任何特殊情况,创建一个

      void foo(Child1 c) {...}
      

      这让事情变得更清楚了:如果你看到这两种方法,你就会知道
      Child1
      (及其子类)有一些特殊的大小写代码,而
      Parent
      和任何其他子类的处理方式都是一样的。

      如果你有更好的选择,那就是糟糕的设计。但有时你不会。如果可能,使用本机Java方法dispatch,而不是
      If instanceof
      惯用语。是的,一般来说,这是糟糕的OO设计。这不一定不好,但你为什么要这样做?这只是语法上的甜点;基本设计是相同的,关于
      foo
      如何响应各种参数类的知识仍然存在于单个类中。它还需要重复调用
      System.out.println
      。@larsmans知道如何响应各种参数类并不是一个坏的设计,只要您知道您涵盖了所有参数类。任何实现visitor的人都知道:):):)即使如此,
      instanceof
      也表明设计糟糕。(我知道你需要它来做
      equals(Object)
      )@TomHawtin-tackline谢谢你纠正我的错误。我可以知道怎么做吗??