【问题标题】:Overriding issues with Java (inheritance)覆盖 Java 的问题(继承)
【发布时间】:2016-03-30 00:25:08
【问题描述】:

计算正方形或长方形的面积。 帮助,所以我必须根据语句应用继承,覆盖,也许重载,在这里,当我尝试计算矩形的面积时,结果是 0.0 我相信这是因为我在子类中的 asignar (assign) 方法没有覆盖那个来自超类。 另外,这个程序是否有效地应用了继承和覆盖(除了我遇到的问题)?

import java.io.*;

class AreaF {
    private double lado; // side

    public void asignar(double b) {
        lado = b;
    }

    public double traerL() {
        return lado;
    }
}

class Cuadrado extends AreaF {
    public double area() {
        double a;
        a = Math.pow(traerL(), 2);
        return a;
    }
}

class Rectangulo extends AreaF {
    private double altura; // height

    public void asignar(double h) {
        double altura = h;
    }

    public double area() {
        double a;
        a = traerL() * altura;
        return a;
    }
}

public class Pro2 {
    public static void main(String[] args) throws IOException {
        double b = 0, h = 0;
        int op;
        Cuadrado obj = new Cuadrado(); // square
        Rectangulo obj2 = new Rectangulo(); // rectangle
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Ingrese la base: ");
        try {
            b = Double.parseDouble(br.readLine());
        } catch (NumberFormatException x) {
            System.out.println(x);
        }
        obj.asignar(b);
         /**
         * 1 - for square
         * 2 - for rectangle
         */
        System.out.println("Ingrese 1 para saber el area de CUADRADO, 2 para RECTANGULO"); 

        op = Integer.parseInt(br.readLine());
        if (op == 1) {
            System.out.println("El area del cuadrado es: " + obj.area()); // sq
                                                                            // area
        } else if (op == 2) {
            System.out.println("Ingrese la altura del rectangulo: "); // height
            try {
                h = Double.parseDouble(br.readLine());
            } catch (NumberFormatException x) {
                System.out.println(x);
            }
            obj2.asignar(h);
            System.out.println("El area del rectangulo es: " + obj2.area()); // rct
                                                                                // area
        } else
            System.out.println("Error!");
    }
}

【问题讨论】:

  • 我不确定,但对我来说类层次结构看起来很奇怪: 1. 类AreaF 有什么好处? 2.在我看来Cuadrado必须继承自Rectangulo,因为正方形是矩形的边缘情况,高度和宽度都相等。
  • 您的主要问题是您创建了两个对象obj 和obj2,当您要求插入基地时,您只在obj 上设置它obj.asignar(b); 之后您问是否当用户选择一个您从未设置过的矩形时,它是一个矩形或正方形obj2.asignar(b);,因此矩形总是为 0。
  • 好吧,如果你想用Square和Rectangle来扩展AreaF,我建议把它改成一个带有函数返回区域的接口。就像现在一样,您在技术上是压倒一切的(添加可选的 @Override 注释)。

标签: java inheritance overloading overriding


【解决方案1】:

我不太确定这项任务的目标是什么,但我会采用以下类层次结构:

interface Figure { // also abstract class can be used there
    abstract double area();
}

class Rectangle implements Figure {
    private double width;
    private double height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    double area() {
        return width * height;
    }
}

class Square extends Rectangle {
    public Square(double side) {
        super(side, side);
    }
}

我简化了main方法,但我认为思路很明确:

public static void main(String[] args) {
    final Rectangle rectangle = new Rectangle(3, 5);
    System.out.println("rectangle.area() = " + rectangle.area()); // result is 15.0
    final Square square = new Square(3);
    System.out.println("square.area() = " + square.area()); // result is 9.0
}

所以,Rectangle 覆盖 Figure 的 area() 方法,Square 从 Rectangle 继承它。

【讨论】:

  • 鉴于 OP 提到的要求和您实现的设计,您不认为使用 interface 会更适合,而不是 abstract类?特别是因为Figure 没有(和/或需要)任何已实现的方法。要更清楚地了解两者之间的区别,请this link。
  • 我同意。实际上我的第一个想法是将它创建为一个接口(我肯定会在生产代码中这样做),但后来我改变了主意。我认为也许对于抽象类,继承的概念对于主题启动器来说会更清楚。但如果至少我们两个认为这里的界面更好,我编辑了我的帖子:)
  • 是的,我也这么认为。无论哪种方式,设计和答案都不错。 :)
【解决方案2】:

你既没有超载也没有压倒一切。你只是躲起来。

重载是指在类中增加一个方法,其中已经存在同名但不同签名的方法。

重写是指在其父类包含同名同名方法的类中添加一个带有@Override属性标记的方法。

隐藏类似于覆盖,只是添加的方法没有标@Override,就是你这里做的。

所以这个问题的答案

这个程序是否有效地应用了继承和覆盖(除了我遇到的问题)?

是没有。

我认为你应该改变你的整个设计。

注意:以下都是我个人的观点。

AreaF 应该是一个抽象类,甚至是一个接口。我认为接口更合适,但您的分配似乎需要您使用继承。所以让我们把它改成一个抽象类:

public abstract class AreaF {
    public abstract double getArea();
}

我看到你有一个正方形和一个矩形作为AreaF 的基类。让我们也实现它们:

public class Square extends AreaF {
    private double length;
    public double getLength() { return length; }
    public void setLength(double length) { this.length = length; }
    @Override // I overrode the getArea method in the super class
    public double getArea() {
        return getLength() * getLength();
    }
}

这里是 Rectangle 类:

public class Rectangle extends AreaF {
    private double width, height;

    // public getters and setters for width and height. You know what I mean.
    @Override
    public double getArea () {
        return getWidth() * getHeight();
    }
}

然后你可以相应地使用方法并得到正确的结果。

【讨论】:

  • 什么? @Override 在 Java 中是可选的(很好的做法,但可选)。您定义的“隐藏”和“覆盖”之间的语义区别是什么?
  • 如果Rectangle 和Square 执行相同的操作,那么使用不同的getArea() 方法有什么好处?
【解决方案3】:

您的代码有很多问题。 1)缩进 2)英文名称。 3)你有一个逻辑错误。 Object1.lado=a,Object1.altura=0;而 Object2.lado=0, Object2.altura=h ==> obj2.area=0...(这是你的错误!)。

这是一个很好的代码。看看它,如果您有任何报价,请随时询问。

import java.io.*;

class AreaF {
    private final double lado; 

    public void asignarLado(double b) { //give mingfullnames (better in english!)
        lado = b;
    }

    public double traerL() {
        return lado;
    }
}

class Cuadrado extends AreaF {
    public double areaCuadrado() {
        double a;
        a = Math.pow(traerL(), 2);
        return a;
    }
}

class Rectangulo extends Cuadrado {
    private double altura; 

    public void asignarAltura(double h) {
        double altura = h;
    }

    public double areaRectangulo() {
        double a;
        a = traerL() * altura;
        return a;
    }
}



public class Pro2 {
    public static void main(String[] args) throws IOException {
        double b = 0, h = 0;
        int op;
        Cuadrado obj = new Cuadrado(); // square

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        try {
            System.out.println("Ingrese la base: ");
            b = Double.parseDouble(br.readLine());
            obj.asignarBase(b);

            System.out.println("Ingrese la altura del rectangulo: "); // height
            h = Double.parseDouble(br.readLine());
            obj.asignarAltura(h);

            System.out.println("Ingrese 1 para saber el area de CUADRADO, 2 para RECTANGULO");
            op = Integer.parseInt(br.readLine());

             if (op == 1) {
                System.out.println("El area del cuadrado es: " + obj.areaCuadrado());
             else if (op == 2) {
                System.out.println("El area del rectangulo es: " + obj.areaRectangulo());
            }
            else
                System.out.println("Error!");
            }
        } catch (NumberFormatException x) {
            System.out.println("Wrong arguments!");
        }finally{
            br.close; //allways close input resurce! 
        }

    }
}

///-------------------------------------------- 这是真正的 O.O 设计。 我使用了一个接口和一种称为 Area 的方法。 和两个类立方体和矩形类。这是真正的方法。

public interface Area{
    public double getArea();
}

class Cuadrado implements Area {
    double base;

    public Cuadrado(double base){
        setBase(base);
    }

    public void setBase(double base) {
        this.base = base;
    }

    @Override
    public double getArea() {
        // TODO Auto-generated method stub
        return base*base;
    }


}

class Rectangulo extends Cuadrado {

    private double hight;

    public Rectangulo(double base,double hight){
        super(base);
        this.hight = hight;
    }

    public void setParams(double base,double hight) {
        this.base = base;
        this.hight = hight;
    }

    @Override
    public double getArea() {
        // TODO Auto-generated method stub
        return base*hight;
    }
}


public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        try {
            System.out.println("Ingrese la base: ");
            double b = Double.parseDouble(br.readLine());

            System.out.println("Ingrese la altura del rectangulo: "); // height
            double h = Double.parseDouble(br.readLine());

            System.out.println("Ingrese 1 para saber el area de CUADRADO, 2 para RECTANGULO");
            int op = Integer.parseInt(br.readLine());

             if (op == 1) {
                Area cuadrado = new Cuadrado(b); // square
                System.out.println("El area del cuadrado es: " + cuadrado.getArea());
             }
             else if (op == 2) {
                Area rectangulo = new Rectangulo(b,h);
                System.out.println("El area del rectangulo es: " + rectangulo.getArea());
            }
            else{
                System.out.println("Error!");
            }
        } catch (NumberFormatException x) {
            System.out.println("Wrong arguments!");
        }finally{
            br.close(); //allways close input resurce! 
        }

    }
}

【讨论】:

  • 作为答案,这是相当低的质量;应该是评论。
  • 首先,我没有给出'-1'。我选择通知你。其次,这只是不是将评论作为答案的理由。
  • 但我的回答是对的……问题的根源确实在于 ob1 和 obj2 是不同的对象。.. :) 他的代码有 X10000 问题。但最大的是 obj1 和 obj2 是两个不同的对象。
  • 请参阅此线程中发布的其他答案,尤其是@AndrejIstomin 的答案。也请看How to answer。
  • 关于错误代码格式的要点。我也同意在代码中使用英语。但我完全不同意你评论的形式。这是不礼貌的。以“我没有完全看你的代码......”开头的评论真的值得得到“-1”,不是吗?
猜你喜欢
  • 1970-01-01
  • 2016-03-16
  • 2020-07-07
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多