Understanding where messages get sent during inheritance


#1

On page 112 we are overriding the bodyMassIndex method within Employee.h. The method is called in main.m as float bmi = [person bodyMassIndex];

What I don’t understand is how the bodyMassIndex method gets called when it looks like the message is being sent to person which is second in the inheritance chain rather than employee which is first in the inheritance chain and where the overridden method exists. Can anyone explain this?


#2

Assume the class Person has a bodyMassIndex method and the class Employee has a bodyMassIndex method. Also assume that Employee inherits from Person.

Then, if x is an instance of Person, sending it the message bodyMassIndex triggers the bodyMassIndex method defined in Person.
If y is an instance of Employee, sending it the message bodyMassIndex triggers the bodyMassIndex method defined in Employee.

Cool so far?

Now, assume the class Person has a terminalVelocity method and the class Employee has no terminalVelocity method.

Then, if x is an instance of Person, sending it the message terminalVelocity triggers the terminalVelocity method defined in Person.
If y is an instance of Employee, sending it the message terminalVelocity triggers the terminalVelocity method defined in Person.

That is, the search starts at the class of the instance. If that class has not defined the method, the superclass is asked. And so on up the tree.


#3

One point of possible confusion: Person and Employee are classes, person (lower-case “p”) is a variable containing an instance of Employee.

Don’t mistake the variable name for an indication of what’s actually contained in it. There is sometimes, but definitely not always, a relationship.


#4

I think I’m getting closer to understanding.

The inheritance chain:
employee–>person–>NSObject

So if I send a message to person instance that does not contain the method terminalVelocity, the message gets re-directed back to employee which has the method terminalVelocity (and if it didn’t have that method we would throw an exception when the messaging discovered it wasn’t in NSOBject either)?

I thought according to the OOP paradigm that person instance would have no “knowledge” of employee, only instances of objects “below” it. Does person instance “know” about employee? “Who” is doing the sending or re-directing here? (sorry about my quotes, I’m still learning the lingo).


#5

OK, maybe I figured this out. What was confusing me was the naming convention in main.m. I thought that the bodyMassIndex message was getting sent to the second instance in the chain called person when in fact it was getting sent to the top of the chain instance called employee. Because *person was used as the instance variable name I was thinking this was the same object receiving the message. I’ve changed the code below in a way that seems to make more sense to me. Hopefully this reasoning is correct.

int main (int argc, const char * argv[])
{
    //note: changed instance name of Employee Class from *person to *employee.  In fact, it could be called *foo.
    @autoreleasepool {
       Employee *employee = [[Employee alloc]init];                    
        [employee setWeightInKilos:96];
        [employee setHeightInMeters:1.8];
        [employee setEmployeeID:15];      
        float bmi = [employee bodyMassIndex];
        NSLog(@"Employee %d has BMI of %f", [employee employeeID], bmi);    
    }
    return 0;
}

#6

You beat me to it; yes, you’ve got it.