有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

    这里有许多问题,其中最关键的是correctly pointed out by Belerafon,缺少父类构造函数(在父类中创建无参数构造函数或将现有构造函数之一调用为super(street、pin、city),您可能希望调用super(street、pin、city)构造函数)

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

    类测试(sic)是一个地址,因为它扩展了地址。因此,必须满足地址合同;i、 你可以把它当作一个地址来使用。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一个地址,包含一个不同的地址。当这是合适的时候,一个类比是a Female Cat既是a 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,因为accronym比HyperTextMarkupLanguage更为人所知),否则使用完整的单词。这也表明类test实际上是EmployeeDetails。在这种情况下,它不是地址,也不应该扩展地址,但它应该封装(包含)地址