Я читаю книгу на Java и в настоящее время на тему Polymorphism
, а также как downcast
ссылочную переменную. Тем не менее, я довольно застрял в понимании концепции downcasting. Ниже приведен пример 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
Книга далее объясняет, что улучшенный итерации цикла массива employees
и вызывает методы toString
и earnings
с Employee
переменной currentEmployee
который присваивается ссылку на другой Employee
в массиве на каждой итерации. В результате вывод иллюстрирует, что конкретные методы для каждого класса вызывают и решаются во время выполнения в зависимости от типа объекта.
Для вызова методов getBaseSalary
и setBaseSalary
на текущем Employee
объекта BasePlusCommissionEmployee
«s, условие оператора используется для проверки, если ссылка на объект является BasePlusCommissionEmployee
объектом, используя InstanceOf оператора и, если условие истинно, объект должен быть downcast от Employee
до BasePlusCommissionEmployee
тип перед вызовом упомянутых методов.
Это серьезно смущает меня, потому что мы можем получить доступ к toString
методу подклассов, но должен обратному приведение объекта для того, чтобы использовать другие методы, а именно getBaseSalary
и setBaseSalary
? Почему это так?
да то, что вы сказали, делает так много смысла для меня. Кстати, почему бы вам сказать, что использование instanceof является плохой практикой? – Scorpiorian83
instanceof - плохая практика, потому что она обычно заменяется кодом, применяющим полиморфизм. См. Ответ GhostCat. Иначе говоря: код 'if (obj instanceof ClassA) {doA(); } else if (obj instanceof ClassB) {doB(); } 'лучше писать путем определения метода' doStuff() 'в суперклассе ClassA и ClassB, переопределяя его в каждом классе, чтобы сделать правильную вещь, а затем заменив код выше на' obj.doStuff() '. –