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

时间:2013-05-27 23:06:03

标签: java c++ casting

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

5 个答案:

答案 0 :(得分:19)

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

(superclass)                               Number
                                   __________/\__________
                                  /       |      |       \
(concrete subclasses)          Integer   Long    Float   Double

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

Integer i = new Integer(8);
Number n = i;   // this is widening conversion; no need to cast

缩小转换:当我们采用不太具体的类型(超类)并尝试将其分配给更具体的类型(子类)时,会发生这种情况,这需要显式转换。

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

您需要注意某些问题,例如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

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

 if( n instanceof Integer) {
      i = (Integer) n;
 }

你为什么要用这个?假设您正在为一些程序制作人员层次结构,并且您有一个名为“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
     }
}

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

答案 1 :(得分:2)

如果某些代码返回包含true / false值的int,您可以将其自身缩短为bool,这正是它所代表的内容。
你也可以这样做。

您可以将char扩展为int,以便与ascii值进行一些比较。

您可以使用Dog的实例并将其扩展为IAnimal以将其传递给函数。

当您在工厂或其他地方IAnimal出于某种原因知道动物类型时,您可以将Dog缩短为List<IAnimal>

答案 2 :(得分:2)

您使用隐式转换来使用不同类型的数值进行数学运算。例如,如果now()以秒为单位返回时间戳:

 long t = now()
 long nextMinute = t + 60

您已完成60(一个int)的隐式扩展转换为long,因此您可以将其添加到t。能够进行此类转换使得数学编码变得更加容易。

答案 3 :(得分:1)

扩展和缩小转换的一个典型示例是某些文件I / O库的工作方式。通常,文件处理库将具有从文件中读取单个字符的函数/方法。如果有一个要读取的字符,该函数应该返回该字符,如果没有剩下字符,它应该返回一个标记值EOF来发出信号。

因为任何字符都可以出现在文件中,所以函数/方法通常会有这个签名:

int readCharacter();

此处,函数返回int,如果读取了一个字符,则该char值保留EOF值,否则将EOF保留为哨兵。 char通常被选为一个太大而不能容纳while (true) { int ch = readCharacter(); if (ch == EOF) break; char actualCharValue = (char) ch; /* process actualCharValue here */ } 的整数。这样,你可以这样做:

{{1}}

希望这有帮助!

答案 4 :(得分:1)

拿这个......

转换 - 专业化 - &gt;当你变得更加普遍时,它被广义化,然后被称为拓宽。

如外科医生 - &gt;医学生。在这种情况下,您不需要投射。因为,外科医生默认是Medico。因此,外科医生可以自然地完成Medico可以做的所有事情。

另一方面, 转换 - 广义 - &gt;当你变得更专业化时,专业化,然后它被称为缩小。

如Medico - &gt;外科医生。那么,在这种情况下,你必须添加铸造。因为,医生可以是外科医生或医生或护士。想想看,如果你让护士对你进行操作......

可怕,对吧???

希望你明白了。