【问题标题】:Writing an OOP with java用java写一个OOP
【发布时间】:2015-09-19 20:10:49
【问题描述】:

我的教授希望我用 Java 编写一个面向对象的程序,它可以解决一些二次方程的次数与定义的 args[0] 一样多,例如 computer-:Desktop User$ java program_name 3 将迭代程序 3 次。(我希望这很清楚够了)。

除了“面向对象的程序”之外,我什么都写好了,我不知道如何使它面向对象,说明并没有给我留下太多的工作空间(除了使用构造函数方法)。

我一直在尝试这样做:

public class assignment {
assignment(double method_inp){
    double coeff = method_inp;
}
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int input_number = Integer.parseInt(args[0]);

    if (input_number > 0) {
        for (int i = 0; i < input_number; i++) {

            // isn't this object oriented?
            assignment a = new assignment(readCoeff(input));
            assignment b = new assignment(readCoeff(input));
            assignment c = new assignment(readCoeff(input)); 

(readCoeff(input) 只是转到扫描仪并让用户输入值。 但似乎我不能使用abc 作为变量。也不会将它们转换为变量,因为它们不能转换为双精度。我能做些什么?有没有更好的方法让我的程序面向对象?

编辑:我不能使用全局变量

编辑:readCoeff(input) 的内容是:

static double readCoeff(Scanner inn) {
    System.out.print("Please enter coefficient of a quadratic equation: ");
    return inn.nextDouble();

【问题讨论】:

  • readCoeff的内容是什么?

标签: java oop object-oriented-analysis


【解决方案1】:

任何时候你使用静态这个词,你都“一般”不在 OOP 模型中。

为什么?

因为静态将状态(在设计意义上)从对象上下文提升到模块上下文。您的所有编程都在静态方法中进行(求解器除外)。

这是我喜欢做的事

public class Program
{
  public static void main(String[] args) {
     Parser p = new MyCommandlineParser();
     Options op = p.Parse(args);

     Solver solver = new Solver();
     s.SolveVariables(op.getTimesToSolve());
     System.out.println("Done.  OOP is about design not programming");
  }
}

从设计开始,然后编程;

【讨论】:

  • 嗯,已经有一个Parserjava.util.Scanner。是的,您的解决方案是完全面向对象的,但不需要像 Java 一样是 Smalltalk,对于如此简单的任务恕我直言,这有点过头了。
  • OOP 或者我更喜欢称之为 (OOD) 都是关于设计的。如果教授(或业务中的客户)最终在此程序上进行构建,那么如果您以易于扩展的方式构建它,那么扩展将更容易;您应该将命令行解析包装在其自己的类中,因此如果您开始解析更多参数,则该逻辑已被封装。您的象牙塔教授也会喜欢这种封装水平。
  • 好吧,这无可争辩。如果 OP 想要构建一个完全从命令行运行的专业二次方程求解器,那就是要走的路
  • @leat 我必须做更多的研究才能理解这个答案,这是我所有其他编程练习的结合。 (我正在学习 Java 课程,我们刚刚学会了如何使用循环,所以我很菜鸟......无论如何,我实际上比这更先进)仍然感谢你非常感谢您的回答,我从未将 OOP 视为 OOD,但这很有意义,在我的教育中前进时我会牢记这一点。
【解决方案2】:

通过强制 OOP 来做一些可以在没有对象的情况下更有效、更干净地完成的事情有点迟钝。但是,有这样的老师(我也知道一些)。所以,这就是我的做法:

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int inputNumber = Integer.parseInt(args[0]);

        if (inputNumber > 0) {
            for (int i = 0; i < inputNumber; i++) {
                int[] coefficients;
                //read coefficients into the array
                QuadraticEquation equation = new QuadraticEquation(coefficients);
                System.out.println(equation.solve());
            }
        }
    }
}


class QuadraticEquation {
    private int[] coefficients;

    QuadraticEquation(int[] coefficients) {
        this.coefficients = coefficients;
    }

    double solve() {
        //solve the equation using coefficients and return the result
    }
}

如果需要,将变量/字段名称替换为更合理的名称。此外,类名应始终为大写。编译器不会抱怨,但这是一个被广泛接受的约定。

现在,在上面的代码中实际发生的是我们定义了一个名为QuadraticEquation 的类,它由它的系数定义,我们将它们传递给构造函数。现在,当对象拥有所有必要的信息时,我们可以在其上调用solve() 来实际做某事,即。 e.给我们结果,我们打印出来(您也可以将所有结果保存在一个数组中并在最后打印出来)。

还要注意我们有两个类。您可以将所有内容合二为一,但我认为您不应该这样做。每个类都应该代表一个可以独立工作的对象(Main 类从这个角度看实际上毫无意义;它只是为了防止main(String[]) 污染其他东西)。

理想情况下,您应该创建一个名为 QuadraticEquation 的单独文件,将 class QuadraticEquation 更改为 public class QuadraticEquation 并在构造函数和方法前加上 public 以使它们可以在任何地方使用,因为它们不与任何特定的东西相关联.我想让事情变得简单,并将所有内容都转储到一个地方,并且因为一个文件中不能有两个公共类,另一个必须是包保护的(默认可见性级别)。

【讨论】:

  • “通过强制 OOP 来做一些可以在没有对象的情况下更有效、更干净地完成的事情有点迟钝。但是,有这样的老师(我也知道一些)。”没有错。练习的目的是测试/练习学生的 OOP 技能,而不是寻找二次方程的解。
  • 是的,但是有更好的练习,例如。 G。包括数据建模的东西。这个只专注于计算,您拥有的唯一模型是方程本身。如果你引入复数,你可以更好地利用它
【解决方案3】:

使用单独的类表示您的Equations(二次)。在类中定义要对操作执行的操作定义。将使用 Equation 的实例访问这些操作。

主类assignment 将接受方程式的数量并在方程式数组中创建实例。

import java.util.Scanner;

class Equation {
  double a, b, c;
  Equation(double a, double b, double c) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
  // Perform the operation on equation using specific methods.
}

public class assignment {

  public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int input_number = Integer.parseInt(args[0]);
    Equation objects[];
    double inputA, inputB, inputC;
    if (input_number > 0) {
      objects = new Equation[input_number];
      for (int i = 0; i < input_number; i++) {
        inputA = readCoeff(input);
        inputB = readCoeff(input);
        inputC= readCoeff(input);
        objects[i] = new Equation(inputA, inputB, inputC);
      }
    }
  }
  static double readCoeff(Scanner inn) {
    System.out.print("Please enter coefficient of a quadratic equation: ");
    return inn.nextDouble();
  }
}

【讨论】:

  • @Gaskoin 嘿,你看过我发布的最新答案吗?我也想看看你的方法。请找点空闲时间。谢谢。
  • 现在好多了:) 我的方法将非常相似。
【解决方案4】:
import java.util.Scanner;

/**
 * Created by EpicPandaForce on 2015.09.20..
 */
public class Main {
    public static void main(String[] args) {
        int iterationCount;
        if (args.length > 0) {
            iterationCount = Integer.parseInt(args[0]);
        } else {
            iterationCount = 1;
        }
        new Main().execute(iterationCount);
    }

    private Scanner scanner;

    public Main() {
        scanner = new Scanner(System.in);
    }

    public void askForCoefficientInput() {
        System.out.println("Please enter the three coefficients");
    }

    public double readCoefficient() {
        return scanner.nextDouble();
    }

    public void execute(int iterationCount) {
        double inputA, inputB, inputC;
        if (iterationCount > 0) {
            for (int i = 0; i < iterationCount; i++) {
                askForCoefficientInput();
                inputA = readCoefficient();
                inputB = readCoefficient();
                inputC = readCoefficient();
                Equation equation = new Equation(inputA, inputB, inputC);
                equation.printResults();
            }
        }
    }

    public static class Equation {
        private double a;
        private double b;
        private double c;

        private double result1;
        private double result2;
        private boolean hasResult;

        public Equation(double a, double b, double c) {
            this.a = a;
            this.b = b;
            this.c = c;
            calculate();
        }

        protected final void calculate() {
            if (a != 0) {
                if ((b * b - 4 * a * c) >= 0) {
                    this.result1 = ((-1) * b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);
                    this.result2 = ((-1) * b - Math.sqrt(b * b - 4 * a * c)) / (2 * a);
                    this.hasResult = true;
                }
            } else {
                if (b != 0) {
                    this.result1 = ((-1) * c) / b;
                    this.result2 = ((-1) * c) / b;
                    this.hasResult = true;
                } else {
                    if (c == 0) {
                        this.result1 = 0;
                        this.result2 = 0;
                        this.hasResult = true;
                    }
                }
            }
        }

        public void printResults() {
            System.out.println(
                    "The equation [" + a + "x^2 " + (b >= 0 ? "+" + b : b) + "x " + (c >= 0 ? "+" + c : c) + "] had " + (this.hasResult() ? "" : "no ") + "results" + (this.hasResult() ? ", these are: [" + this
                            .getFirstResult() + "] and [" + this.getSecondResult() + "]." : "." + "\n"));
        }

        public double getFirstResult() {
            return this.result1;
        }

        public double getSecondResult() {
            return this.result2;
        }

        public boolean hasResult() {
            return this.hasResult;
        }
    }
}

结果:

>> Executing quadratic.Main

Please enter the three coefficients
1 -8 12
The equation [1.0x^2 -8.0x +12.0] had results, these are: [6.0] and [2.0].

Please enter the three coefficients
3 8 12
The equation [3.0x^2 +8.0x +12.0] had no results.

Process finished with exit code 0

【讨论】:

  • 是的,它不处理复数。
  • 这很好,但我不能使用它,因为它有类变量。(虽然感谢发布它,它实际上解释了我的很多问题。
  • 我不确定你应该如何在不使用字段变量的情况下实现封装......我很高兴它有帮助。另外,我认为@leaf 的回答是最清楚的;每种类型的动作都有自己的类,它为使用的每个类提供了一组明确的责任。例如,在我的例子中,printResults() 方法作为Equation 的一部分并没有真正意义,Equation 并不需要了解任何关于打印的知识,并且应该是它自己的类在Equation 上运行。唉,这样重构很容易,但像这样自顶向下设计是一种技能。
猜你喜欢
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多