Проблемы с toString () и переопределением методов - PullRequest
0 голосов
/ 27 февраля 2020

У меня проблема с этим кодом. Это не правильно рассчитать площадь. Мне это нужно для расчета площади поперечного сечения цилиндра / поршня и площади поверхности цилиндра. Если вы заметили вывод, кажется, что оба значения являются одними и теми же, когда я использую метод getArea (). Java не понимает ли getter, какой getArea () использовать? сильный текст Я пытаюсь переопределить getArea () [Площадь поверхности] с помощью getArea () [площадь поперечного сечения], но он не работает?

import java.util.Scanner;

class Main {
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    System.out.println(
        "\n\nInput the radius, then the height, then if the cylinder is filled (input 1 if it is filled and input 0 if not, and then enter the color");

    double radius = scan.nextDouble();
    double height = scan.nextDouble();
    int filled = scan.nextInt();

    boolean isFilled;
    if (filled == 1) {
      isFilled = true;
    } else {
      isFilled = false;
    }

    String c = scan.nextLine();
    String x = scan.nextLine();

    Cylinder cyl = new Cylinder(radius, height, isFilled, x);
    System.out.println("\n\n This is a Cylinder and its properties");
    System.out.println(cyl);

    Piston small= new Piston();
    System.out.println ("\n\n This is small Piston");
    System.out.println(small);

    Piston big = new Piston(55.6, 1234.4, true, "red", 1200, 12.3);
    System.out.println ("\n\n This is big Piston");
    System.out.println(big);
  }
}

class Shape {
  private String color = "yellow";
  private boolean filled;

  public Shape() {

  }

  public Shape(String color, boolean filled) {

    this.color = color;
    this.filled = filled;
  }

  public String getColor() {
    return color;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public boolean isFilled() {
    return filled;
  }

  public void setFilled(boolean filled) {
    this.filled = filled;
  }

  public String toString() {
    return "\nThe color is : " + color + " and shape fill is : " + filled;

  }

}

class Cylinder extends Shape {
  private double cylinderRadius;
  private double cylinderHieght;

  public Cylinder() {
    cylinderHieght = 10;
    cylinderRadius = 2.5;
  }

  public Cylinder(double height, double radius) {
    cylinderRadius = radius;
    cylinderHieght = height;
  }

  public Cylinder(double height, double radius, boolean filled, String color) {
    super(color, filled);
    cylinderRadius = radius;
    cylinderHieght = height;
  }

  public double getRadius() {
    return cylinderRadius;
  }

  public double getHieght() {
    return cylinderHieght;
  }

  public double getArea() {
    double p = 3.14;
    return 2 * p * cylinderRadius * cylinderRadius + 2 * p * cylinderRadius * cylinderHieght;
  }

  public double getVolume() {
    double p = 3.14;
    return p * cylinderRadius * cylinderRadius * cylinderHieght;
  }

  @Override
  public String toString() {
    return super.toString() + " \nRadius= " + cylinderRadius + " Height= " + cylinderHieght
        + " Cylinder total surface Area= " + getArea() + " volume= " + this.getVolume() + ".";
  }
}

class Piston extends Cylinder{
  private double shaftLength;
  private double myPressure;

  public Piston(){
    shaftLength=1;
    myPressure=1;
  }
  public Piston(double height, double radius, boolean filled, String color, double length, double pressure){
    super(height, radius, filled, color);
    shaftLength=length;
    myPressure=pressure;
  }
  public double getShaftLength(){
    return shaftLength;
  }
  public double getPressure(){
    return myPressure;
  }
  @Override
  public double getArea(){
    return getRadius()*getRadius()*3.14;
  }
  public double getVolume(){
    return super.getVolume();
  }
 @Override
  public String toString(){
    return super.toString()+"\n the cross sectional area of Piston = "+this.getArea()+" shaftlength="+shaftLength+" pressure="+myPressure+" .";
  }
}

Вот вывод, если я вставлю радиус 5 и высота 10.

Введите радиус, затем высоту, затем, если цилиндр заполнен (введите 1, если он заполнен, и введите 0, если нет, а затем введите цвет 5 10 1 Синий

Это Цилиндр и его свойства

Цвет: Синий и форма: Истина Радиус = 10,0 Высота = 5,0 Общая площадь цилиндра Площадь = 942,0 Объем = 1570,0 .

Это маленький поршень

Цвет: желтый, а заливка формы: ложь Радиус = 2,5 Высота = 10,0 Цилиндр общая площадь поверхности = 19,625 объем = 196,25. t площадь поперечного сечения поршня = 19,625 длина шага = 1,0 давление = 1,0.

Это большой поршень

Цвет: красный, форма заливки: true Радиус = 1234,4 Высота = 55,6 Общая площадь цилиндра = 4784554,150400002 * 1 024 * громкость = 2,6602121076224005E8. Площадь поперечного сечения поршня = 4784554.150400002 Длина вала = 1200.0 Давление = 12,3.

1 Ответ

1 голос
/ 27 февраля 2020

Чтобы уточнить - похоже, что такова ситуация:

  1. У вас есть один класс (Cylider), который определяет метод (getArea()) для выполнения одной вещи. Другой метод в Cylider (toString()) вызывает этот метод getArea().
  2. Затем вы подклассифицируете Chylidar с дочерним типом (Piston) и переопределяете функцию getArea() на сделайте другое.
  3. Теперь, когда ваш код в классе Cylider вызывает метод getArea(), вы ожидали, что он будет использовать Cylider версию getArea() , потому что код был написан в том же классе , но на самом деле он использовал переопределенную Piston версию getArea() , потому что объект, на который вы вызывали , на самом деле был поршнем .

Это на самом деле не ошибка или даже проблема, которую нужно решить - это просто функция того, как Java разрешает вызовы методов. Он выберет тот, который наиболее специфицирован c, учитывая фактический тип объекта, с которым вы работаете (даже если во время компиляции не очевидно, каким будет этот тип) не тот, который написан ближе всего к виду вызывающего абонента.

На самом деле нет способа обойти это. Я бы воспринял это как признак того, что ваш дизайн плохой - или, по крайней мере, идиоматизм c. Переопределение функций предназначено для того, чтобы дать вам другой, более правильный способ вычисления той же идеи для другого типа , а не просто как способ повторного использования имен функций.

Самое простое изменение, вероятно, состоит в том, чтобы просто создать новый метод для Cylinder с именем getCylinderArea(). Cylider.getArea() может вызывать эту функцию по умолчанию, но вы можете назвать ее явным в Cylider.toString(), если хотите, чтобы эта функция когда-либо использовала только метод простого вычисления Цилиндра.

В качестве альтернативы, возможно, поршень не должен на самом деле является подтипом Cylinder, потому что, хотя они и имеют некоторые общие характеристики, поршень не может заменить универсальный c цилиндр везде, где вы будете использовать цилиндр - например, при расчете площади. Посмотрите Принцип замещения , чтобы узнать больше.

Лично я склонен вообще избегать наследования именно по этой причине. На самом деле я бы порекомендовал просто использовать интерфейсы и плоскую иерархию в этом случае вместо этого.

Этот поток StackOverflow может быть интересен, если вы хотите получить более подробную информацию о вызове супер методов.

...