在OCP书中,我读到协方差有这样的规则:
给定继承的返回类型A和重写的返回类型B,是否可以将B的实例分配给A的引用变量而不进行强制转换?如果是,那么它们是协变的。此规则适用于基本体类型和对象类型
如果该规则适用于基元类型,并且我可以在没有强制转换的情况下将int值分配给长变量(所以它们是协变的(,那么为什么代码不编译(协变返回类型(?我想这句话或者我对它的理解有问题吗?
class Class1
{
long method()
{
return 1L;
}
}
class Class2 extends Class1
{
public static void main(String[] args)
{
int B = 1;
long A = B; // no cast
}
// @Override
// int method() { return 1; } // does not compile // 'method()' in 'B' clashes with 'method()' in 'A'; attempting to use incompatible return type
}
您的问题与类型转换无关,而是与继承有关。您正试图重写一个方法并将返回类型更改为不兼容的类型。这是不可能的,但如果是的话,那将是非常危险的。方法签名,包括返回类型,是一种不允许破坏的约定。您的调用类取决于该约定,因此,如果可以重写基元类型,您可能会遇到一个简单的问题,即您的调用类别不知道实际的返回类型。但通常使用多态性,因此在编译时,您必须依赖于所使用的引用类型的约定。请参阅以下简单示例(由于最后一行的原因无法编译(:
public class Class1 {
long method() {
return 3; //int, but cast before the value is returned
}
}
class Class2 extends Class1 {
public static void main(String[] args) {
int B = 1;
long A = B; // no cast
}
int method2() { //renamed to get this compiled
return 3;
}
}
class SimpleClass {
public static void main(String[] args) {
int i = 1;
long j = 2;
long l = i + j; //this compiles because int is implicitly cast to long
//int k = i + j; // This doesn't compile because long can't be cast
//implicitly to int
}
}
class Class3 {
void whatIsTheResult() {
Class1 class1 = new Class1();
Class1 class12 = new Class2(); //No problem due to polymorphism, both
//objects have the reference type Class1,
// but actually, class12 is of type Class2
Class2 class2 = new Class2();
long a = class1.method() + class2.method2(); //By contract, method
//returns a long, method2 returns an int
int b = class1.method() + class2.method2(); // Same contract, but long
//can't be 'cast down' to int, so doesn't compile
}
}