有人可以解释为什么你会使用扩大或缩小转换?我已经阅读了很多关于这些但没有人给我一个实际的例子。谢谢!
答案 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;外科医生。那么,在这种情况下,你必须添加铸造。因为,医生可以是外科医生或医生或护士。想想看,如果你让护士对你进行操作......
可怕,对吧???
希望你明白了。