[英]Writing Java constructor for child class that takes parent object
Is it possible to use a parent object to instantiate a child object? 是否可以使用父对象实例化子对象? The class Length2 extends Length1 with the addition of an instance variable.
Length2类通过添加实例变量来扩展Length1。 Common I tried to make a copy constructor that takes the Length1 as a param and sets the extra ivar to 0, but I'm still being told I cannot convert from Legnth1 to Length2.
常见问题,我试图制作一个将Length1作为参数并将额外的ivar设置为0的副本构造函数,但仍然有人告诉我我无法从Legnth1转换为Length2。 I suppose there may be some implicit casting taking place... have a look.
我想可能会发生一些隐式转换...看看。
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
}
}
Like Leo said, if L1 is the super type of L2, that implies L2 has all of L1 and then some. 就像Leo所说的那样,如果L1是L2的超类型,则意味着L2拥有所有L1,然后拥有所有L1。 So if you try to create an L2 from an L1, information will be missing.
因此,如果尝试从L1创建L2,则会丢失信息。
My answer is no, you can't unfortunately. 我的回答是不,您不能不幸。 But you can try to push all useful information from L1 into L2 using some method like L2 = L2.valueOf(L1) that copies all the known fields from L1 into L2, leaving the missing ones empty.
但是您可以尝试使用某种方法(例如L2 = L2.valueOf(L1))将所有有用的信息从L1推送到L2,该方法将所有已知字段从L1复制到L2,而将丢失的字段留空。 You have to write this method by hand.
您必须手动编写此方法。 Maybe you can save some time reusing some L1 constructor in L2.
也许您可以节省一些时间,以便在L2中重用某些L1构造函数。
You can't do that. 你不能那样做。 Length2 IS A Length1, so you can always assign a
Length2
object to a Length1
reference (you never have to cast it). Length2是一个Length1,因此您始终可以将
Length2
对象分配给Length1
引用( Length1
)。 You can also assign a Length1
reference that points to a Length2
object to another reference declared as Length2
. 您还可以将一个指向
Length2
对象的Length1
引用分配给另一个声明为Length2
引用。 In this case you need an explicit cast because the compiler doesn't know at compile time that the Length1
reference actually is a Length2
. 在这种情况下,您需要进行显式转换,因为编译器在编译时不知道
Length1
引用实际上是Length2
。 But what you are trying to do is not possible, since Length1
IS NOT A Length2
. 但是您尝试做的事情是不可能的,因为
Length1
不是Length2
。
It's like saying that Car extends Vehicle
. 就像说
Car extends Vehicle
。 You can always point to a Car
and say Car
. 您总是可以指向
Car
并说出Car
。
Car c = new Car();
It's always OK. 总是可以的 And you can always point to one and say
Vehicle
: 您总是可以指向一个说出
Vehicle
:
Vehicle v = new Car();
No problem. 没问题。 The only problem you'll have here is if you decide to call, say, the
printLicensePlate()
method of Car
which doesn't exist in Vehicle, which has a melhod called printSpeed()
. 您在这里遇到的唯一问题是,如果您决定调用例如
Car
中不存在的Car
的printLicensePlate()
方法,该方法具有一种称为printSpeed()
。 Since a Car
IS A `Vehicle, you can always call: 由于
Car
是车辆,因此您可以随时致电:
c.printSpeed();
c.printLicensePlate();
and 和
v.printSpeed();
But you can't call: 但您不能致电:
v.printLicensePlate();
even though you know that v
is a Car
. 即使您知道
v
是Car
。 This is the case where you use a cast, to convert the reference. 在使用强制转换来转换引用的情况下就是这种情况。 This is illegal:
这是非法的:
c = v; // WRONG
because the at compile time we don't know what's really in c
, since new Car()
only happens at runtime . 因为在编译时我们不知道
c
到底是什么,因为new Car()
仅在运行时发生。 So you tell the compiler "trust me, this is really a Car
" by doing: 因此,您通过执行以下操作告诉编译器“相信我,这确实是一辆
Car
”:
c = (Car) v;
But what you did was something like: 但是您所做的是这样的:
Car c = new Vehicle(); // WRONG
You pointed to a generic Vehicle
and said Car
. 您指着一辆通用
Vehicle
然后说Car
。 While a Car
is always a Vehicle
, a Vehicle
may not be a car. 尽管
Car
始终是Vehicle
,但Vehicle
可能不是汽车。 (Using the c
reference, the compiler believes you can legally call c.printLicensePlate()
, but at runtime the object you find has no such method. So even if you could pass this by the compiler by casting the reference, it wouldn't work and would produce a ClassCastException
at runtime.) (使用
c
引用,编译器认为您可以合法地调用c.printLicensePlate()
,但是在运行时,您找到的对象没有此类方法。因此,即使您可以通过强制转换引用将其传递给编译器,也不会工作,并且会在运行时产生ClassCastException
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.