代码之家  ›  专栏  ›  技术社区  ›  DCR

类型转换不适用于继承类

  •  -1
  • DCR  · 技术社区  · 3 年前

    我有以下课程:

    形状 长方形 广场

    Shape是父类,Rectangle扩展Shape,Square扩展Rectangle。我使用 StringBuilder和以下代码:

    for (int i = 0; i < 2; i++){
        x = Math.random() * 100;
        y = Math.random() * 100;
    
                      
        if (i % 2 == 0){
            width = Math.random() * 100;
            height = Math.random() * 100;
            Rectangle z = new Rectangle(x, y, height, width);
            list.add(z);
        }else if (i % 2 == 1){
            side = Math.random() * 100;
            Square z = new Square(x, y, side);
            list.add(z);
        }
    }
    
    for(Shape s : list){
       System.out.println(s.getStr0());
       System.out.println(s.getStr1());
    }
    

    将打印出以下内容:

    Rectangle with height: 91.19 and width: 73.70, Centered at X: 14.21 Y: 81.81
    Has area: 6720.81
    Has perimeter: 329.78
    
    Square with side: 66.42, Centered at X: 36.06 Y: 95.86
    Has area: 4411.18
    Has perimeter: 265.67
    

    有没有办法让我键入cast或将正方形转换为矩形,这样我 获取以下内容:

    Rectangle with height: 91.19 and width: 73.70, Centered at X: 14.21 Y: 81.81
    Has area: 6720.81
    Has perimeter: 329.78
    
    Rectangle with height: 66.42 and width 66.42, Centered at X: 36.06 Y: 95.86
    Has area: 4411.18
    Has perimeter: 265.67
    

    以下是完整的代码:

    
    import java.util.ArrayList;
    public class Shape{
        private double x;
        private double y;
        private StringBuilder str = new StringBuilder();
        private StringBuilder str0 = new StringBuilder();
        private StringBuilder str1 = new StringBuilder();
        private StringBuilder str2 = new StringBuilder();
    
        public Shape(double x, double y){
            this.x = x;
            this.y = y;  
            String x1 = String.format("%.2f",this.x);
            String y1= String.format("%.2f",this.y);
            getStr().append("Centered at X: " + x1 + " Y: " + y1 );
        }
    
        public Shape(){
        }
    
        public static void main(String[] args){
            System.out.println('\u000C');
    
            ArrayList<Shape> list = new ArrayList<Shape>();
            double x;
            double y;        
            double height;
            double width;
            double side;
    
            for (int i = 0; i < 2; i++){
                x = Math.random() * 100;
                y = Math.random() * 100;
    
                if (i % 2 == 0){
                    width = Math.random() * 100;
                    height = Math.random() * 100;
                    Rectangle z = new Rectangle(x, y, height, width);
                    list.add(z);
                }else if (i % 2 == 1{
                    side = Math.random() * 100;
                    Square z = new Square(x, y, side);
                    list.add(z);
                }
            }
    
            for(Shape s : list){
                System.out.println(s.getStr0());
                System.out.println(s.getStr1());
            }
        }
        public String toString(){
            String x = String.format("%.2f",this.x);
            String y = String.format("%.2f",this.y);
                    
            return "Centered at X: " + x + " Y: " + y ;
        }
        public double calculateArea(){
            return -999.99;
        }
        public double calculateCircumference(){
            return -999.99;
        }
        public double calculatePerimeter(){
            return -999.99;
        }
        public double getX(){
            return this.x;
        } 
        public void setX(double x){
            this.x = x;
        }
        public double getY(){
            return this.y;
        }
        public void setY(double y){
            this.y = y;
        }
        public StringBuilder getStr(){
            return this.str;
        } 
        public void setStr(StringBuilder str){
            this.str = str;
        }
        public StringBuilder getStr0(){
            return this.str0;
        }
        public void setStr0(StringBuilder str0){
            this.str0 = str0;
        } 
        public StringBuilder getStr1(){
            return this.str1;
        } 
        public void setStr1(StringBuilder str1){
            this.str1 = str1;
        }    
    }
    
    public class Rectangle extends Shape{
        private double height;
        private double width;
        
        public Rectangle(double x, double y, double height, double width){
            super(x, y);
            this.height = height;
            this.width = width;
            
            String area = String.format("%.2f",this.calculateArea());
            String perimeter = String.format("%.2f",this.calculatePerimeter());
            
            
            
            getStr0().append(toString());        
            getStr1().append("Has area: " + area + "\n");
            getStr1().append("Has perimeter: " + perimeter + "\n");
            
        }
        public Rectangle(){
            
        }
        public double calculateArea(){
            return height * width;
        }
        public double calculatePerimeter(){
            return 2 * height + 2 * width;
        }
        public String toString(){
            
            String height = String.format("%.2f",this.height);
            String width = String.format("%.2f",this.width);        
            return "Rectangle with height: " + height + " and width: " + width +
            ", " + super.toString();
        }
    }
    
    public class Square extends Rectangle{
        double side;
        StringBuilder squarestr = new StringBuilder();
    
        public Square(double x, double y, double side){
            super(x, y, side, side);
            this.side = side;
    
            String area = String.format("%.2f",this.calculateArea());
            String perimeter = String.format("%.2f",this.calculatePerimeter());
    
            getStr0().delete(0,getStr0().length() );
            
    
            getStr1().delete(0,getStr1().length() );
    
            getStr0().append(toString());
            
    
            getStr1().append("Has area: " + area + "\n");
            getStr1().append("Has perimeter: " + perimeter + "\n");
            
            
        }
    
        public String toString(){
    
            String side = String.format("%.2f",this.side);
    
            return "Square with side: " + side + ", " + getStr() ;
        }
    
        public double calculateArea(){
            return side * side;
        }
    
        public double calculatePerimeter(){
            return 4 * side;
        }
    }
    
    
    1 回复  |  直到 3 年前
        1
  •  1
  •   rzwitserloot    3 年前

    “铸造”这个词只解决了一件事,那就是 句法结构 。java源代码中的任何内容看起来像: (SomeType) someExpression 。您不应该将该术语用于除此之外的任何事情(这在讨论中应该很少出现),因为强制转换运算符用于 3件完全无关的事情 ,但如果您不太熟悉java,可能会混淆3。你似乎在做什么。最好使用更清晰的术语来避免这种混淆。

    那么这三个有什么不同呢? 彻底地 。在你认为这没有意义之前,请记住:

    String a = "Hello";
    String b = ", world!";
    String c = a + b;
    
    int x = 5;
    int y = 10;
    int z = x + y;
    

    使用完全相同的运算符( + )对于2 完全无关 事物:字符串连接和数字相加。

    这同样适用于强制转换运算符。

    转变

    强制转换操作转换任何内容的唯一方法是如果parens中的类型是基元 。仅此而已。你问:“我能把一个正方形转换成矩形吗?或者通过某种方式进行强制转换,使该正方形以某种方式使用矩形的toString吗?”答案是强调的: ,因为强制转换运算符 无法转换任何内容 ,除非您正在将一个基元强制转换为另一个。 int x = (int) someDouble; 是实际的转换,但只有8个基元可以做到这一点(并且在实践中, boolean 也做不了这份工作。

    类型检查

    当parens中的类型为 一个基元,强制转换运算符进行类型检查。给定:

    Object o = someExpression;
    String x = (String) o;
    

    该强制转换运算符在类文件中注入以下代码:

    1. 解析表达式。这包括遵循 o 指针(在java中,所有非基元都是指针,在java术语中,是“引用”;不过是一样的),并检查在那里找到的对象。当然,那是 至少 Object 但它可能是比这更具体的东西。它是一个吗 String 还是某种亚型?
    2. 如果是, 什么都不做 。没有转换任何内容。该表达式的类型(整个 (String) o 节点)是 一串 因此,这将允许您例如调用 .toLowerCase() 基于结果。这并不是因为这个铸造操作神奇地使 o 增益a toLowerCase() 作用诺诺; o 指向一个字符串,并且所有字符串都有 到小写() 作用 javac 只是不让你调用它,因为它在跟随时不知道它找到的对象 o 确实是一根弦。演员阵容确实如此,因为。。。
    3. 如果答案是否定的,抛出 ClassCastException 。同样,不会发生转换。

    强制类型转换所做的其他事情是一个类型断言——在这里,您可以指定某个类型的表达式,从而生成ZERO字节码。你只是在告诉编译器。这就是当你粘贴泛型( <> 东西)在那里:

    List<Object> o = new ArrayList<Object>();
    List raw = o;
    List<String> uhoh = (List<String>) raw;
    o.add(5);
    String x = uhoh.get(0);
    

    上面的代码编译了,但您确实收到了警告。证明这不会注入任何代码( List 已经得到保证,并且 <String> 部分,这是泛型,类型断言也是,即编译器只接受你的话)。此代码将引发 ClassCastException 在最后一行,如果你运行它,这很奇怪,因为那里没有演员阵容。通常,这种使用强制运算符的方法只能作为最后的手段,并且总是会生成警告,因为这是不安全的。

    推荐文章