我正在阅读一本关于Java的书,目前正在学习
该书进一步解释了增强的for循环是如何迭代数组
为了在当前的
这让我感到困惑,因为我们能够访问子类的
多态性
主题以及如何向下转型(downcast)
一个引用变量。然而,我对理解向下转型的概念感到困惑。下面是我正在跟随的示例的UML图。
对于所有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循环是如何迭代数组
employees
并使用Employee
变量currentEmployee
调用toString
和earnings
方法的,而这个变量在每次迭代时都被赋值为数组中不同的Employee
的引用。因此,输出结果说明了每个类的特定方法都会被调用,并且根据对象类型在执行时进行解析。为了在当前的
Employee
对象上调用BasePlusCommissionEmployee
的getBaseSalary
和setBaseSalary
方法,需要使用条件语句检查对象引用是否为BasePlusCommissionEmployee
对象,并使用instanceof运算符进行判断,如果条件为真,则必须将对象从Employee
类型向下转换为BasePlusCommissionEmployee
类型才能调用上述方法。这让我感到困惑,因为我们能够访问子类的
toString
方法,但必须向下转型对象才能使用其他方法,即getBaseSalary
和setBaseSalary
。为什么会这样呢?
if (obj instanceof ClassA) { doA(); } else if (obj instanceof ClassB) { doB(); }
最好通过在 ClassA 和 ClassB 的超类上定义方法doStuff()
,并在每个类中重写它以执行正确的操作,然后用obj.doStuff()
替换上述代码。 - Paul Brinkley