是否可以使用父对象来实例化子对象?类Length2通过添加实例变量来扩展Length1。常见的我尝试制作一个复制构造函数,将Length1作为参数并将额外的ivar设置为0,但我仍然被告知我无法从Legnth1转换为Length2。我想可能会发生一些隐含的演员......看看。
public class Length1 extends Length implements Comparable<Length1>{
protected int miles;
protected int yards;
public Length1(){ //default constructor
miles = 0;
yards = 0;
}
public Length1(int m, int y){ //constructor
miles = m;
yards = y;
}
public void setYards(int x){
yards = x;
}
public void setMiles(int x){
miles = x;
}
public int getYards(){
return yards;
}
public int getMiles(){
return miles;
}
...
public class Length2 extends Length1 {
protected int feet;
public Length2(){ //default constructor
super(0,0);
setFeet(0);
}
public Length2(int m, int y, int f){ // constructor
super(m,y);
setFeet(f);
}
public Length2(Length1 x){
super(x.miles,x.yards);
setFeet(0);
}
public void setFeet(int x){
feet = x;
}
public int getFeet(){
return feet;
}
...
public class LengthTest{
public static void main(String[] args) {
Length1 a,b,c,d,e,f;
Length2 g,h,i,j;
a = new Length1(78,1610);
b = new Length1(77,1694);
c = new Length1();
d = new Length1();
g = new Length2(32,1022,1);
h = new Length2(31,1700,2);
i = new Length2();
j = new Length2();
j = c; //problem occurs here
}
}
答案 0 :(得分:0)
就像Leo所说,如果L1是L2的超级类型,那意味着L2具有L1的全部,然后是一些。因此,如果您尝试从L1创建L2,则信息将丢失。
答案 1 :(得分:0)
我的回答是否定的,不幸的是,你不能。但是你可以尝试使用L2 = L2.valueOf(L1)之类的方法将L1中的所有有用信息推送到L2,将L1中的所有已知字段复制到L2中,将丢失的字段留空。你必须手工编写这个方法。也许你可以节省一些时间在L2中重用一些L1构造函数。
答案 2 :(得分:0)
你不能这样做。 Length2是一个Length1,因此您始终可以将Length2
对象分配给Length1
引用(您永远不必投射它)。您还可以将指向Length1
对象的Length2
引用分配给另一个声明为Length2
的引用。在这种情况下,您需要一个显式转换,因为编译器在编译时不知道Length1
引用实际上是Length2
。但是你要做的是不可能的,因为Length1
不是Length2
。
就像说Car extends Vehicle
一样。您始终可以指向Car
并说出Car
。
Car c = new Car();
总是好的。你总是可以指向一个并说Vehicle
:
Vehicle v = new Car();
没问题。您在这里遇到的唯一问题是,如果您决定拨打车辆中不存在的printLicensePlate()
Car
printSpeed()
方法,该方法有一个称为{{1}的方法}}。由于Car
是一个“车辆”,您可以随时致电:
c.printSpeed();
c.printLicensePlate();
和
v.printSpeed();
但你不能打电话:
v.printLicensePlate();
即使您知道v
是Car
。这是您使用强制转换来转换引用的情况。这是非法的:
c = v; // WRONG
因为at 编译时间我们不知道c
中的真实情况,因为new Car()
只发生在运行时 EM>。所以你告诉编译器&#34;相信我,这真的是Car
&#34;通过做:
c = (Car) v;
但你所做的是:
Car c = new Vehicle(); // WRONG
您指向通用Vehicle
并说Car
。虽然Car
始终为Vehicle
,但Vehicle
可能不是汽车。 (使用c
引用,编译器认为你可以合法地调用c.printLicensePlate()
,但是在运行时你找到的对象没有这样的方法。所以即使你可以通过编译引用来传递它,它不会起作用,并且会在运行时生成ClassCastException
。)