编写带有父对象的子类的Java构造函数

时间:2014-02-05 01:43:49

标签: java class constructor parent

是否可以使用父对象来实例化子对象?类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


    }

}

3 个答案:

答案 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();

即使您知道vCar。这是您使用强制转换来转换引用的情况。这是非法的:

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。)