扩展/缩小转换的实际应用?

Her*_*tus 11 c++ java casting

有人可以解释为什么你会使用扩大或缩小转换?我已经阅读了很多关于这些但没有人给我一个实际的例子.谢谢!

Bra*_*n K 20

(Java)扩展和缩小转换与相关类型之间的转换有关.例如,抽象(超级)类与其(子)子类之间的关系; 让我们使用java.lang.Number类(抽象)和直接子类Integer.我们在这里:

(superclass)                               Number
                                   __________/\__________
                                  /       |      |       \
(concrete subclasses)          Integer   Long    Float   Double
Run Code Online (Sandbox Code Playgroud)

扩展转换:如果我们采用特定类型(子类)并尝试将其分配给不太具体的类型(超类),则会发生转换.

Integer i = new Integer(8);
Number n = i;   // this is widening conversion; no need to cast
Run Code Online (Sandbox Code Playgroud)

缩小转换:当我们采用不太具体的类型(超类)并尝试将其分配给更具体的类型(子类)时需要显式转换.

Number n = new Integer(5); // again, widening conversion
Integer i = (Integer) n;   // narrowing; here we explicitly cast down to the type we want - in this case an Integer
Run Code Online (Sandbox Code Playgroud)

您需要注意某些问题,例如ClassCastExceptions:

Integer i = new Integer(5);
Double d = new Double(13.3);
Number n;

 n = i; // widening conversion - OK
 n = d; // also widening conversion - OK

 i = (Integer) d;  // cannot cast from Double to Integer - ERROR

 // remember, current n = d (a Double type value)
 i = (Integer) n;  // narrowing conversion; appears OK, but will throw ClassCastException at runtime - ERROR
Run Code Online (Sandbox Code Playgroud)

处理此问题的一种方法是使用if带有instanceof关键字的语句:

 if( n instanceof Integer) {
      i = (Integer) n;
 }
Run Code Online (Sandbox Code Playgroud)

你为什么要用这个?假设您正在为一些程序制作人员层次结构,并且您有一个名为"Person"的通用超类,它将名字和姓氏作为参数,子类"Student","Teacher","Secretary"等.这里您最初可以创建一个通用人员,并将其(通过继承)分配给学生,该学生将在其构造函数中设置studenID的附加变量字段.您可以使用单个方法将更通用(更宽)的类型作为参数,并处理该类型的所有子类:

 public static void main(String[] args) {
     Person p = new Student("John", "Smith", 12345);
     printInfo(p);
 }

 // this method takes the wider Person type as a parameter, though we can send it a narrower type such as Student if we want
 public static void printInfo(Person p) {
     System.out.println("First: " + p.getFirstName());
     System.out.println("Last: " + p.getLastName());
     if (p instanceof Student) {
         System.out.println( (Student)p).getStudentID() );  // we cast p to Student with Narrow Conversion which allows us to call the getStudentID() method; only after ensuring the p is an instance of Student
     }
}
Run Code Online (Sandbox Code Playgroud)

我意识到这可能不是理想的处理方式,但为了演示,我认为它有助于展示一些可能性.