【问题标题】:Decide what constructor call based on user input根据用户输入决定调用什么构造函数
【发布时间】:2015-12-29 22:10:53
【问题描述】:

我需要询问用户他想要绘制的图形有多少边,然后调用正确的构造函数来实例化对象。

下面是我尝试使用 IF 语句(或者我可以使用 switch)来解决答案,但我不知道这是否是最好的方法,可能是 Java 继承和多态。

所有类都继承了Figure类。

类图:

      --------------- Figure ---------------
      ^         ^             ^            ^
      |         |             |            |
      |         |             |            |
   Circle    Triangle      Rectangle     Exagone

主类:

import java.util.Scanner;

class Draw {

   static void main(String[] args){

       Scanner userInput = new Scanner(System.in);
       int num_sides;

       //user input
       System.out.println("How many sides has the figure you want to draw?");   
       num_sides = userInput.nextInt();


       //---> deciding what constructor to call with if statements

       if(num_sides == 0){
          Figure f1 = new Circle();
       }
       else if(num_sides == 3){
          Figure f1 = new Triangle(); 
       }
       //...
       else{
          System.out.println("Error. Invalid sides number");
       }


   }
}

类代码:

class Figure{

    private int sides;

    public Figure(int num_sides){
       sides = num_sides;
    }
}


class Circle extends Figure{

   public Circle(){
      super(0);
   }

}

//... all the other classes has the same structure of Circle

【问题讨论】:

    标签: java oop inheritance


    【解决方案1】:

    工厂方法

    你考虑过Factory Method Pattern吗?基本上,你有一个类似这样的方法:

    public Figure createInstance(int numSides) {
        Figure figure = null;
    
        switch(numSides) {
        case 0:
            figure = new Circle();
            break;
        case 3:
            // etc...
            // Make a case for each valid number of sides
            // Don't forget to put a "break;" after each case!
        default:
            // Not a valid shape; print your error message
        }
        return figure;
    }
    

    让那个工厂方法来做决定。

    【讨论】:

      【解决方案2】:

      这是一个很好的例子,说明何时使用factory design method。标准是有一个工厂类来确定要调用的构造函数,然后返回该对象。就个人而言,我倾向于将其放入基类的静态方法中(请随意评论为什么这可能很糟糕)。

      【讨论】:

        【解决方案3】:

        解决这个问题的一种方法是向您的 Figure 类添加一个工厂方法来构造其他图形。这样可以将代码保存在一个地方,并且便于 Figure 的客户使用。

        class Figure{
        
            private int sides;
        
            /* package */ Figure(int num_sides){
                sides = num_sides;
            }
        
            public static Figure createFigure(int num_sides) {
                if (num_sides == 0) {
                    return new Circle();
                } else if (num_sides == 4) {
                    return new Square();
                }
                throw new IllegalArgumentException("Invalid number of sides");
            }
        }
        
        
        class Circle extends Figure{
        
            public Circle(){
                super(0);
            }
        
        }
        
        class Square extends Figure{
        
            public Square(){
                super(4);
            }
        
        }
        

        【讨论】:

          【解决方案4】:

          您使用的 IF 不是嵌套的,嵌套 if 的示例是:

          if(condition1) {
              if(con2)
                  //body
          }
          

          从性能方面来说,通常使用:switch-case 会更好。由于这里没有太多案例,else if 可以解决问题,但要知道,由于 JVM,switch 在更多案例时效率更高。

          【讨论】:

          • 你说得对,我不知道我为什么写嵌套 if。我正在编辑我的帖子。尽管您的回答是正确的,但我主要关心的不是性能,而是更多关于编写更具可读性和可重用性的代码,如果语句过多,可能会变得不可读。
          • 然后在body中使用带有switch的工厂方法
          • 切换效率更高吗?我原以为由于 if 语句可能具有树状性质,它们可以获得 log n 时间,而 switch case 需要 n。
          • 没有。切换实际上(在许多情况下)更快,因为它是使用 JVM 中的特殊字节码实现的,而 IF 必须因此检查,因此在 O(n) 中。您不能在树中实现 IF,因为条件(可以)不同,因此不能排序,只能检查。
          【解决方案5】:

          我会按照建议使用工厂设计模式,但如果边数 > 0 并以边数作为参数,我也会创建一个通用构造函数。想一想:您可以将 360 度或 2 PI rad 除以边数,然后将角绘制在一个虚拟圆上。重复使用您的代码,使所有可能的边数成为可能,但值得注意的例外是 0 表示圆。

          【讨论】:

            【解决方案6】:

            您的方法建议您有一个具有确定要创建的图形的边数的属性的类,而不是每个图形的单独类。然后向用户询问边数是有意义的,您可以将数字传递给您的类 Multigon 的构造函数并完成它。这似乎是更好的模型,因为没有需要考虑的专业化或扩展,只是数量不同。你的人物都是同一级别的,他们都以连续的方式在多个步骤中旋转。耙子是一个不同的类别,十字架也是。

            此外,我认为圆有一侧。一条线有两条(前后绘制),下一条是三角形。零是一个点。

            但要回答您的问题,switch 语句会比 if 更好。毕竟,您要处理的是案例,而不是条件。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-01
              • 2021-12-26
              • 1970-01-01
              • 2012-03-14
              • 2021-04-01
              • 2017-07-21
              相关资源
              最近更新 更多