【问题标题】:Polymorphic Subclass Object method in Array not working数组中的多态子类对象方法不起作用
【发布时间】:2017-09-11 09:10:24
【问题描述】:

首先我尝试研究我的问题,但我不知道如何表达我的问题......所以我不确定是否有一个问题可以解决我的问题,也不确定这是否是最好的措辞我的问题也是。

所以,我有一个超类形状

public abstract class Shape {
protected String name;
protected String type;
public Shape(){
    name = "";
    type = "";
}
public void print (){
    System.out.printf("Name = %s, Type = %s", name, type);
}

}

和一个 2D 子类

public abstract class TwoDimensionalShape extends Shape{
protected double length;
protected double area;
public TwoDimensionalShape(double length){
    if (length<0.0)
        throw new IllegalArgumentException("ERROR: POSITIVE NUMBER REQUIRED");
    this.length = length;
    type = "Two Dimensional Shape";
}
public abstract void getArea();
@Override
public void print(){
System.out.printf("Name = %s, Type = %s, Length of side = %d, Area = %d",
name, type, length, area);
}
}

以及几个扩展 2D 的较小子类(以及另一个几乎相同的 3D 类)。我的问题是测试代码,它不计算面积。类测试代码

Circle S1 = new Circle(2.5);
etc.
shapesArray[0] = S1;
etc.
for(Shape CS : shapesArray){
CS.getArea();
if(CS.Type == "Three Dimensional Shape"){
CS.getVolume();
}
CS.print();
System.out.println(" ");
    }
}

我删除了 getArea 和 getVolume 方法,打印语句运行良好。这使我认为每个子类与超类交互的方式存在问题,但是,子类打印方法会覆盖并返回正确的值(区域除外:()

使用 area 和 volume 命令,代码无法编译,我收到此错误

ShapeTest.java:25:错误:找不到符号 CS.getArea();

三次。

这是其中一个子类,以防它包含解决方案所需的重要信息。

public class Circle extends TwoDimensionalShape {
public Circle(double length){
    super(length);
    name = "Circle";
}
@Override
public void getArea(){
    area = Math.PI * length * length;
}
@Override
public void print(){
System.out.printf("Name = %s, Type = %s, Radius = %f, Area = %f",
name, type, length, area);
}
}

我没有足够的经验来完全理解这个问题,我一直在改变循环、变量的位置和类中的方法,但我没有取得进展。感谢您阅读这个冗长的问题,并感谢您提供的任何帮助。

【问题讨论】:

  • 并提示:你有一个错误在那里......stackoverflow.com/questions/513832/…......不要使用==......看起来你现在负担过重。此时您可能应该退后一步,更多地关注真正的基础知识。

标签: java arrays inheritance foreach polymorphism


【解决方案1】:

您的 Shape 类型没有声明该方法。

编译器不知道您打算将 TwoDimensionalShape 对象放入该数组中。它只看到你说:这个数组包含Shapes;和形状没有其他两种方法!

所以你可以这样做:

  • 声明该数组仅包含 TwoDimensionalShape 对象。当然,那你就不能加3D了
  • 使用if (thing is instanceof TwoDimensionalShape) {,然后转换为该类型
  • 然后:您不需要 string 类型。所有对象都有一个;并且那个 class 已经定义了它的确切类型。这就是您使用instanceof 来确定类型的原因;不是通过添加字符串字段并将该字符串(使用 == 的错误方式)与其他字符串进行比较!

【讨论】:

  • 您的解释帮助我理解了故障,谢谢。
【解决方案2】:

你的超级类Shape应该有你想通过java的多态特性访问的所有方法。 有人会将 的子类型实例分配给超类型变量,以统一方式处理所有可能的子类型类,例如使用超类型类声明(但可能被覆盖)的方法。

我对你的课程做了一些小改动。

abstract class Shape {
    protected String name;
    protected String type;

    public Shape() {
        name = "";
        type = "";
    }

    public void print() {
        System.out.printf("Name = %s, Type = %s", name, type);
    }

    public abstract void getArea();

    public abstract void getVolume();

}
// ----------------
abstract class TwoDimensionalShape extends Shape {
    protected double length;
    protected double area;

    public TwoDimensionalShape(double length) {
        if (length < 0.0)
            throw new IllegalArgumentException(
                    "ERROR: POSITIVE NUMBER REQUIRED");
        this.length = length;
        type = "Two Dimensional Shape";
    }

    @Override
    public void print() {
        System.out.printf(
                "Name = %s, Type = %s, Length of side = %d, Area = %d", name,
                type, length, area);
    }
}
//------------------
class Circle extends TwoDimensionalShape {
    public Circle(double length) {
        super(length);
        name = "Circle";
    }

    @Override
    public void getArea() {
        area = Math.PI * length * length;
    }

    @Override
    public void print() {
        System.out.printf("Name = %s, Type = %s, Radius = %f, Area = %f", name,
                type, length, area);
    }

    @Override
    public void getVolume() {
        System.out.println("Vaolume method invoked");
    }
}
//------------------
public class Dim {

    public static void main(String[] args) {
        Shape[] shapesArray = new Shape[10];
        Circle S1 = new Circle(2.5);
        shapesArray[0] = S1;
        for (Shape CS : shapesArray) {
            if (CS != null) {
                CS.getArea();
                if (CS.type.equals("Three Dimensional Shape")) {
                    CS.getVolume();
                }
                CS.print();
                System.out.println(" ");
            }
        }
    }
}

【讨论】:

  • 嘿 Narayana,感谢您发布此答案,我从之前的评论中不确定如何措辞 if (CS.type.equals("Three Dimensional Shape")) { CS.getVolume() ; } 感谢您的帮助
猜你喜欢
  • 2021-09-04
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 2015-06-09
  • 1970-01-01
  • 2020-05-25
相关资源
最近更新 更多