在不进行类型转换的情况下访问父类型的arraylist中的特定子类型方法,仅在运行时才知道创建子类型

时间:2020-11-07 08:20:41

标签: java

我有以下父类:

public class Employee {
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

和2个扩展父级的子类:

public class FullTimeEmployee extends Employee {
    private double salary;

    public FullTimeEmployee(String name, double salary) {
        super(name);
        this.salary = salary;
    }

    public double getSalary() {
        return salary*2;
    }
}

public class PartTimeEmployee extends Employee {
    private double salary;

    public PartTimeEmployee(String name, double salary) {
        super(name);
        this.salary = salary;
    }   

    public double getSalary() {
        return salary;
    }   
}

方案: 我正在使用ArrayList包含有关员工的信息。 ArrayList是在程序开始时创建的,并且添加到Arraylist中的雇员类型是扩展父级的子级,仅在运行时知道通过用户输入

public class EmployeeApplication {

    public static void displayInfo(Employee employee) {
        
        // How do I access the method getSalary() that belong to the specific type determined on runtime?
        System.out.println(employee.getSalary()); //  <--- ???
    }
    
    
    public static void main(String[] args) {
        
        Scanner keyboardInput = new Scanner(System.in);
            
        System.out.println("Type of employee to add into arraylist: ");
        String userInput = keyboardInput.nextLine();
        
        // ArrayList to contain information about employees
        ArrayList<Employee> employeeAL = new ArrayList<Employee>();
        
        // Type of employee being created and added into ArrayList is dynamic and only known at run time based on user input
        if(userInput.equals("full")) {
            employeeAL.add(new FullTimeEmployee("John", 1000));
        }
        else {
            employeeAL.add(new PartTimeEmployee("John", 500));
        }
        
        displayInfo(employeeAL.get(0));
        
        keyboardInput.close();      
    }
}   

现在的问题是: 如何访问属于在运行时确定的特定子类型的方法getSalary()?由于从ArrayList检索的对象是父类型。请注意,工资属性仅属于子类

我当前的实现方式是检查子类型,将其类型转换为该子类型,最后访问属于该子类型的方法。

正在尝试避免类型转换,因为我认为就良好的Java编码实践而言,我做错了事情。我在这里丢失了一些东西,但我只是不知道

我考虑过的另一种方法是在父类中实现方法getSalary(),并在子类中覆盖它,这样,我不会不必强制转换,但我不知道这是否是正确的做法,因为 salary属性与Employee根本没有关系

// Parent
public class Employee {
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    // ADDED THIS <----
    public double getSalary() {
        return 0.0;
    }
}

// Child
public class FullTimeEmployee extends Employee {
    private double salary;

    public FullTimeEmployee(String name, double salary) {
        super(name);
        this.salary = salary;
    }

    // ADDED THIS <----
    @Override
    public double getSalary() {
        return salary*2;
    }
}

我做错了什么,最好的Java编码实践是什么?

1 个答案:

答案 0 :(得分:0)

您可以将Employee实现为抽象,并添加getSalary()作为抽象方法来强制Employee的子类实现该方法

public abstract class Employee {
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    abstract protected double getSalary();
}