为什么子类运行Superclass构造函数?

时间:2015-03-08 00:01:19

标签: java inheritance arraylist

当我运行此代码时,我只是尝试使用轮班详细信息和员工填充列表,我已经在超类中预先制作了一个员工生成器,所以我认为不重复代码是一种好习惯。我可以创建移位数组列表并填充它,但每次创建移位对象时,它都会显示EmployeeSheet字段。

继承人EmployeeSheet班:

import java.util.*;

public class EmployeeSheet
        extends Employee {
    private ArrayList<Employee> empSheet;
    private ProductionWorker pworker;
    private ShiftSupervisor sworker;

    /**
     * Constructs a list of randomly selected employees and displays the list.
     */
    public EmployeeSheet() {
        empSheet = new ArrayList<Employee>();

        Random empPicker = new Random();

        for (int i = 0; i < 20; i++) {
            int id = empPicker.nextInt(20);
            if (id < 12) // roll for production worker
            {
                System.out.println("Adding Production Worker");
                empSheet.add(generateProductionWorker());
            } else //roll for Shift supervisor
            {
                System.out.println("Adding Shift supervisor");
                empSheet.add(generateShiftSupervisor());
            }
        }
        Iterator iterator = empSheet.iterator();
        while (iterator.hasNext()) {
            System.out.println("");
            System.out.println(iterator.next());

        }
    }

    /**
     * Generates a Production Worker
     * @return The fields that make up a Production worker
     */

    public ProductionWorker generateProductionWorker() {
        Random rng = new Random();
        int numberOfEmployeeNames = Ename.length;
        ProductionWorker tempPworker = new ProductionWorker();

        String employeeName = Ename[rng.nextInt(numberOfEmployeeNames)];
        tempPworker.setEmployeeName(employeeName);

        int numberOfEmployeeNumbers = Empnum.length;
        String employeeNumber = Empnum[rng.nextInt(numberOfEmployeeNumbers)];
        tempPworker.setEmployeeNumber(employeeNumber);

        int yearHired = rng.nextInt(35) + 1980;
        tempPworker.setEmployeehireyear(yearHired);

        double weeklySalary = rng.nextInt((100) * 100);
        tempPworker.setEmployeeweeklyearning(weeklySalary);

        int hourlyRate = rng.nextInt(20) + 10;
        tempPworker.setHourlyRate(hourlyRate);

        pworker = tempPworker;

        return tempPworker;

    }

    /**
     * Generates a ShiftSupervisor employee
     * @return the Fields that make up a shift supervisor
     */

    public ShiftSupervisor generateShiftSupervisor() {
        Random ran = new Random();
        int numberOfEmployeeNames = Ename.length;
        ShiftSupervisor tempSworker = new ShiftSupervisor();

        String employeeName = Ename[ran.nextInt(numberOfEmployeeNames)];
        tempSworker.setEmployeeName(employeeName);

        int numberOfEmployeeNumbers = Empnum.length;

        String employeeNumber = Empnum[ran.nextInt(numberOfEmployeeNumbers)];
        tempSworker.setEmployeeNumber(employeeNumber);

        int yearHired = ran.nextInt(35) + 1900;
        tempSworker.setEmployeehireyear(yearHired);

        double weeklySalary = ran.nextInt((100) * 100);
        tempSworker.setEmployeeweeklyearning(weeklySalary);

        int goalsMet = ran.nextInt(100) + 1;
        tempSworker.setGoalsCleared(goalsMet);

        double yearlySalary = ran.nextInt((40000) + 40000);
        tempSworker.setYearlySalary(yearlySalary);

        sworker = tempSworker;

        return tempSworker;

    }

    public int checkSize() {
        return empSheet.size();
    }
}

继承班班:

import java.util.*;

public class Shift
        extends EmployeeSheet {

    private ArrayList<Employee> shiftDetails;
    private ProductionWorker pWorker;
    private ShiftSupervisor sWorker;

    public Shift() {
        this.generateShift();

    }
    // instance variables - replace the example below with your own


    /**
     * Constructor for objects of class Shift
     */

    public void generateShift() {
        shiftDetails = new ArrayList();

        Random supervisorCount = new Random();
        int ssID = supervisorCount.nextInt(3);
        for (int i = 0; i < ssID; i++) {

            shiftDetails.add(this.generateShiftSupervisor());
        }

        Random productionCount = new Random();
        int prodID = productionCount.nextInt(15) + 5;
        for (int d = 0; d < prodID; d++) {

            shiftDetails.add(this.generateProductionWorker());
        }
    }

    public ProductionWorker generateProductionWorker() {
        pWorker = super.generateProductionWorker();
        return pWorker;
    }
    public ShiftSupervisor generateShiftSupervisor() {
        sWorker = super.generateShiftSupervisor();
        return sWorker;

    }

}

为什么会发生这种情况?

2 个答案:

答案 0 :(得分:4)

  

为什么子类运行超类构造函数?

构造基础对象。否则它将是未构造的,继承语义将是不完整的。

  

每当我创建shift对象时,它都会显示EmployeeSheet字段。

因为EmployeeSheet的构造函数显示这些字段。

  

为什么会发生这种情况?

因为Shift扩展了EmployeeSheet。

答案 1 :(得分:3)

您在Java中编写的任何构造函数都是从对另一个构造函数的调用开始的。如果你没有明确地写它,那么编译器会为你编写以下行作为构造函数的第一行:

super();

这意味着为了构造任何实例,您需要首先构造父类的实例(除了没有父类的Object类)。

Object Oriented Programming的角度来看,这是有道理的,因为当A继承自B时,它意味着A“是一个”B,具有某种特定的状态或行为。在您的情况下,似乎您没有使用继承来描述“是一个”关系,这可能是一个设计错误。

我的意思是,似乎EmployeeSheet“不是”员工。您最好仅使用Composition来建模此关系。