有人可以解释一下为什么你会使用扩大或缩小转换吗?我已经阅读了很多关于这些的内容,但没有人给我一个实际的例子。谢谢!
5 回答
(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,该 Student 将在其构造函数中设置一个额外的 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
}
}
我意识到这可能不是处理事情的理想方式,但为了演示,我认为它有助于展示一些可能性。
如果某些代码返回一个int
包含真/假值的值,您可以自己将bool
其缩短为它正确表示的值。
你也可以做相反的事情。
您可以扩大 a char
toint
以与 ascii 值进行一些比较。
您可以获取一个实例Dog
并将其扩展IAnimal
为将其传递给函数。
无论出于何种原因IAnimal
,Dog
当您知道工厂或其他地方的动物类型时,您都可以缩短 a 。List<IAnimal>
您使用隐式转换对不同类型的数值进行数学运算。例如,如果now()
返回一个以秒为单位的时间戳作为 long:
long t = now()
long nextMinute = t + 60
您已经完成了 60(一个 int)到 long 的隐式扩展转换,因此您可以将其添加到t
. 能够进行这样的转换使数学更容易编码。
扩大和缩小转换的一个典型示例是某些文件 I/O 库的工作方式。通常,文件处理库将具有从文件中读取单个字符的函数/方法。如果有一个字符要读取,函数应该返回那个字符,如果没有字符,它应该返回一个标记值 EOF 来表示这个。
因为任何字符都可以出现在文件中,所以函数/方法通常具有以下签名:
int readCharacter();
在这里,如果读取了一个字符,该函数将返回int
一个值,否则将其作为哨兵。 通常选择一个整数,它太大而不能保存在 a 中。这样,您可以这样做:char
EOF
EOF
char
while (true) {
int ch = readCharacter();
if (ch == EOF) break;
char actualCharValue = (char) ch;
/* process actualCharValue here */
}
希望这可以帮助!
拿着这个...
转换 - 专业化 -> 广义化,当你变得更一般化时,它被称为扩大。
例如外科医生-> Medico。在这种情况下,您不需要强制转换。因为,外科医生默认是Medico。因此,外科医生可以执行 Medico 可以执行的所有工作,这是很自然的。
另一方面,转换 - 广义 -> 专业化,当您变得更加专业化时,它被称为缩小。
例如Medico -> Surgeon。那么,在这种情况下,您必须添加强制转换。因为,医生可以是外科医生、内科医生或护士。想想看,如果你让护士给你做手术……
可怕,对吧???
希望你明白了。