Array中的Polymorphic Subclass Object方法无法正常工作

时间:2017-04-15 06:13:18

标签: java arrays inheritance foreach polymorphism

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

所以,我有一个Superclass Shape

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方法,print语句运行正常。这让我觉得每个子类与超类的交互方式存在问题,但子类打印方法会覆盖并返回正确的值(区域除外:()

使用区域和卷命令,代码无法编译,我收到此错误

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);
}
}

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

2 个答案:

答案 0 :(得分:0)

您的类型Shape不会声明该方法。

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

所以你可以这样做:

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

答案 1 :(得分:0)

你最超级的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(" ");
            }
        }
    }
}