有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java对象上的超类如何工作?

比如说我有一个像这样的超级级Ugrad:

public class Ugrad{

    int DM = 140;
    int perYear() { return DM/4; }
}

我有一个名为Grad的子类,如下所示:

public class Grad extends Ugrad{
    int DM = 28;
     int perYear() { return DM/2; };

现在,我有一个tester类,在其中我做了一些打印来学习对象是如何工作的,比如:

//In the line-comments I denote what the result of the print will be.
public class Tester{
  public void main(String[] args){
     Grad g = new Grad();
     System.out.println(g.DM); // 28
     System.out.println(g.perYear()); // 14
     Ugrad u = (Ugrad) g;
     System.out.println(u.DM); //140
     System.out.println(u.perYear()); //14
  }
}

我的问题是super class cast如何在对象上工作? 为什么当u.DM等于140时,u.perYear打印14等于g.DM/2


共 (1) 个答案

  1. # 1 楼答案

    1. 您正在将子类转换为超类。 这是向上投射(或隐式投射),根据:Inheritance -> Casting Obects 这意味着这个角色可以隐式完成。 你不必在作业后添加施法操作符。 每个Grad对象都隐式地是类Upgrad的对象,因为 你的声明:Grad extends Upgrad。 也就是说,这将起作用:
    Upgrad u = g;
    
    1. 您已经重写了perYear()方法。 在强制转换到超类并调用此方法后,由于Java的多态性原则和覆盖规则,它将保持在Grad类中实现的状态: 事实上,这个问题已经在Stackoverflow上得到了回答。 引用Learning Java by Daniel Leuck & Patrick Niemeyer

      When there are multiple implementations of a method in the inheritance hierarchy of an object, the one in the “most derived” class (the furthest down the hierarchy) always overrides the others, even if we refer to the object through a reference of one of the superclass types.

    2. 这与隐藏字段不同。 下面最好描述隐藏或隐藏字段: Subclassing and inheritance -> Shadowed Variables 链接中使用了一组不同的类型,但含义相同:

      Another important point about shadowed variables has to do with how they work when we refer to an object by way of a less derived type (a parent type). For example, we can refer to a DecimalCalculator object as an IntegerCalculator by using it via a variable of type IntegerCalculator. If we do so and then access the variable sum, we get the integer variable, not the decimal one:

      DecimalCalculator dc = new DecimalCalculator();
          

      IntegerCalculator ic = dc;

      int s = ic.sum; // accesses IntegerCalculator sum

      正如Inheritance -> What You Can Do in a Subclass中所说:

      You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).

    测试代码:

    
    class Ugrad {
    
        int DM = 140;
        int perYear() { return DM/4; }
    }
    
    class Grad extends Ugrad {
        int DM = 28; // we have *hidden* Upgrad.DM field by
        int perYear() { return DM/2; }
     }
    
     public class UpgradGrad {
      public static void main(String[] args){
         Grad g = new Grad();
         System.out.println(g.DM); // Grad.DM field is accessed directly, thus output = 28
         System.out.println(g.perYear()); // 14
         Ugrad u = g; // this will work because of implicit casting to a superclass
         System.out.println(u.DM); // g is casted to u. Grad.DM was hiding Upgrad.DM. Thus Upgrad.DM emerges.
         System.out.println(u.perYear()); // because g is just referred to as Upgrad, its original Grad.perYear() method will be called
      }
    }