Этот пример демонстрирует мощь объектно-ориентированного программирования.
Поскольку ab является экземпляром B, любой вызов метода для ab будет использовать функции, определенные в B, , даже если эти функции вызываются косвенно через функцию, определенную в суперклассе .
Пример настолько абстрактен, что достоинства этого могут быть неясны. Позвольте мне привести чуть более реалистичный пример:
class Employee
{
... bunch of stuff ...
void calcPay()
{
pay=hoursWorked*hourlyRate;
}
void produceCheck))
{
calcPay();
calcTaxes();
calcBenefitDeductions();
printCheck();
}
}
class Salesman extends Employee
{
void calcPay()
{
pay=sales*commissionRate;
}
}
... somewhere else ...
for (Employee employee1 : employeeList)
{
employee1.produceCheck();
}
Я опускаю все виды деталей, чтобы подчеркнуть: этот код не будет компилироваться.
Но вот в чем суть: у продавца есть другой метод расчета зарплаты, чем у других сотрудников: им платят комиссионные, а не почасовые. (В реальной жизни у нас, по-видимому, также есть наемные работники, но, как я уже сказал, я упрощаю.) Функция для расчета заработной платы любого типа сотрудника вызывается из более крупной функции, которая также выполняет другие функции. Прелесть объектно-ориентированного программирования в том, что мы можем вызывать внешнюю функцию и не заботиться о том, является ли объект, против которого мы ее вызываем, обычным сотрудником или продавцом. Каждый объект знает, что это такое, и вызывает правильную функцию. В последних нескольких строках примера у нас есть некоторая структура, которая включает в себя как обычных сотрудников, так и продавцов, и мы можем проходить и обрабатывать их все без необходимости проверять их тип. Без ООП нам пришлось бы постоянно писать код вроде: "if (type == SALESMAN) ... иначе if (type == HOURLY) ..."