java – 多态性和向下转换问题

我正在读一本关于Java的书,目前关于多态性主题,以及如何向下转换参考变量.但是,我很难理解向下转换的概念.下面是我正在关注的示例的uml.

java  – 多态性和向下转换问题

对于BasePlusCommissionEmployee的所有对象,他们的基本工资增加10%.其他Employee子类是按照正常情况进行的. PayrollSystemTest包含运行应用程序的主要方法.

// Fig. 10.9: PayrollSystemTest.java
// Employee hierarchy test program.

public class PayrollSystemTest
{
    public static void main(String[] args)
    {
        // create subclass objects
        SalariedEmployee salariedEmployee =
            new SalariedEmployee("John", "Smith", "111-11-1111", 800.00);
        HourlyEmployee hourlyEmployee =
            new HourlyEmployee("Karen", "Price", "222-22-2222", 16.75, 40.0);
        CommissionEmployee commissionEmployee =
            new CommissionEmployee(
            "Sue", "Jones", "333-33-3333", 10000, .06);
        BasePlusCommissionEmployee basePlusCommissionEmployee =
            new BasePlusCommissionEmployee(
            "Bob", "Lewis", "444-44-4444", 5000, .04, 300);

        System.out.println("Employee processed individually:");

        System.out.printf("%n%s%n%s: $%,.2f%n%n",
            salariedEmployee, "earned", salariedEmployee.earnings());
        System.out.printf("%s%n%s: $%,.2f%n%n",
            hourlyEmployee, "earned", hourlyEmployee.earnings());
        System.out.printf("%s%n%s: $%,.2f%n%n",
            commissionEmployee, "earned", commissionEmployee.earnings());
        System.out.printf("%s%n%s: $%,.2f%n%n",
            basePlusCommissionEmployee,
            "earned", basePlusCommissionEmployee.earnings());

        // create four-element Employee array
        Employee[] employees = new Employee[4];

        // initialize array with Employees
        employees[0] = salariedEmployee;
        employees[1] = hourlyEmployee;
        employees[2] = commissionEmployee;
        employees[3] = basePlusCommissionEmployee;

        System.out.printf("Employees processed polymorphically:%n%n");

        // generically process each element in array employees
        for (Employee currentEmployee : employees)
        {
            System.out.println(currentEmployee); // invokes toString

            // determine whether element is a BasePlusCommissionEmployee
            if (currentEmployee instanceof BasePlusCommissionEmployee)
            {
                // downcast Employee reference to
                // BasePlusCommissionEmployee reference
                BasePlusCommissionEmployee employee =
                    (BasePlusCommissionEmployee) currentEmployee;

                employee.setBaseSalary(1.10 * employee.getBaseSalary());

                System.out.printf(
                    "new base salary with 10%% increase is: $%,.2f%n",
                    employee.getBaseSalary());
            } // end if

            System.out.printf(
                "earned $%,.2f%n%n", currentEmployee.earnings());
        }  // end for

        // get type name of each object in employees array
        for (int j = 0; j < employees.length; j++)
            System.out.printf("Employee %d is a %s%n", j,
                employees[j].getClass().getName());
    } // end main
} // end class PayrollSystemTest

本书进一步解释了增强的for循环迭代数组员工并使用Employee变量currentEmployee调用方法toString和income,并在每次迭代时为数组中的不同Employee分配引用.因此,输出说明了调用每个类的特定方法,并在执行时根据对象的类型进行解析.

为了在当前的Employee对象上调用BasePlusCommissionEmployee的方法getBaseSalary和setBaseSalary,条件语句用于通过使用instanceof运算符来检查对象引用是否是BasePlusCommissionEmployee对象,如果条件为true,则必须将对象从Employee转发到在调用前面提到的方法之前,BasePlusCommissionEmployee类型.

这让我很困惑,因为我们能够访问子类的toString方法,但是为了使用其他方法,即getBaseSalary和setBaseSalary,必须向下转换对象?为什么会这样?

解决方法:

因为toString()是在Object中定义的,因此在每个类中都可用.基本工资的getter和setter仅在BasePlusCommissionEmployee中可用,因此您无法通过Employee引用调用它(如果引用其他类型会发生什么?).

这个例子不是你在实际代码中看到的.使用instanceof确定要做的是糟糕的风格.

上一篇:java – 如何通过参数类型选择重载方法?


下一篇:java – 重载和重写方法中的多态性