如何将父对象作为参数传递给子类的构造函数

时间:2014-04-26 09:53:06

标签: java inheritance constructor

在下面的代码中,我有几个问题要问: 我无法将类Address的对象作为参数传递给其子类EmployeeAddress的构造函数。为什么这样 ?它给出了错误,如参数不匹配..没有参数传递.... 我想在show方法中调用类Address中的EmployeeAddress对象。怎么做?

class Address {
    public String street;
    int pin;
    String city;

    Address(String street, int pin, String city) {
        this.street = street;
        this.pin = pin;
        this.city = city;
    }
}

class EmployeeAddress extends Address {
    int empid;
    public String empname;
    Address add;

    EmployeeAddress (int empid, String empname, Address add){
        this.empid = empid;
        this.empname = empname;
        this.add = add;
    }

    void show() {
        System.out.println("my name is " + empname + "and my empid is " + empid);
    }
}

class Employee {

    public static void main(String ar[]) {
        Address ad1 = new Address("mystreet", 201301, "nyk");

        EmployeeAddress a1 = new EmployeeAddress(123, "kin", ad1);

        a1.show();
    }

    /*
     * public String toString() { return
     * "my name is "+a1.empname+"and my pin is "+ad1.pin ; }
     */
}

2 个答案:

答案 0 :(得分:5)

这里有许多问题,其中最关键的是correctly pointed out by Belerafon,缺少父类构造函数(在父代中创建无参数构造函数或者将现有构造函数之一调用为super (街道,别针,城市),可能你想打电话给超级(街道,别针,城市)建设者。)

缺少默认构造函数或调用适当的构造函数

类测试(原文如此)地址,因为它扩展了地址。因此,它必须符合地址合同;即你可以像使用地址一样使用它。 Address只有一个构造函数Address(String street, int pin, String city),它初始化它,以便可以无错误地调用其所有方法。所以你需要调用适当的超级构造函数,所以

test(int empid, String empname, Address add){
    super(add.street, add.pin, add.city); //<-- this gives the parent part of the class all the information it needs
    this.empid = empid;
    this.empname = empname;
    this.add = add; //<-- somewhat strange, covered later
}

在子类的构造函数中传递父类并保留引用

这可能有合法用途但在这种情况下我担心它被不恰当地使用。在这种情况下,类test 一个地址,包含一个不同的地址。这种情况适当的类比是Female Cat两者都是Cat并且还可以包含小猫形式​​的猫。

很可能你根本不想扩展地址,或者你想停止将地址传递给构造函数(取决于类test 地址或包含地址。所以:

在这些示例中,我使用了正确的Java命名约定,请参阅下面的

class Test{
    int empid;
    public String empname;
    Address add;

    Test(int empid, String empname, Address add){
        this.empid = empid;
        this.empname = empname;
        this.add = add;
    }

    void show() {
        System.out.println("my name is " + empname + "and my empid is " + empid);
    }
}

class Test extends Address {
    int empid;
    public String empname;


    Test(int empid, String empname, String street, int pin, String city){
        super(street, pin, city); //<-- this gives the parent part of the class all the information it needs
        this.empid = empid;
        this.empname = empname;

    }

    void show() {
        System.out.println("my name is " + empname + "and my empid is " + empid);
    }
}

使用Java编码样式约定

班级名称以大写字母开头。对象变量名称以小写字母开头。因此,test课程应为Test。如果您不遵守这些惯例,人们将无法阅读您的代码。

经过长时间的思考,我发现empid可能是employeeID。这些类型的缩写也违反了样式约定,因为它们使代码难以阅读,除非在特殊情况下使用完整的单词(例如HTML,因为这个首字母缩略词比HyperTextMarkupLanguage更为人所知)。这也表明课程test实际上是EmployeeDetails。在这种情况下,它不是一个地址,不应该扩展地址,但它应该封装(包含)一个地址。

答案 1 :(得分:2)

您的代码的问题是类Address没有定义默认构造函数。在EmployeeAddress的构造函数中,java尝试调用Address的无参数构造函数,因为Address是父类。但它不能,因为Address中没有无参数构造函数。添加一个可以解决问题