Person gets employeeID


#1

I tried setting
Person *person = [[Employee alloc] init];
instead of
Employee *person = [[Employee alloc] init];

    [person setEmployeeID:22];

gets a warning “Person may not respond to setEmployeeID”, but the program still runs ok.
Does NSObject look down the chain as well as up?


#2

The method search only climbs up the inheritance ladder.

Might I peek at your Person.h and main.m?


#3

Realised what I’m overlooking.
Even though I declare *person as an instance of Person, I then do [[Employee alloc] init]; so I figure it’s creating an instance of Employee, though it still puts a warning, but doesn’t throw an exception.

If instead I do

Person *person = [[Person alloc] init];

or even

Employee *person = [[Person alloc] init];

it throws the exception.

Getting the hang of this, slowly :slight_smile:


#4

so if you write

Person *person = [[Employee alloc] init];

you just get a warning :question:

is it creating an instance of Employee? or Person?


#5

[quote=“alexander2020”]so if you write

Person *person = [[Employee alloc] init];

you just get a warning :?: [/quote]

You should not receive a warning for that code, no. An Employee is definitely a Person.

You should receive a warning if you later attempt to send a message to that instance which is only valid for Employees, since the compiler doesn’t know for certain whether it’s an Employee or a Person inside that object.

It is creating an Employee instance.


#6

We call Objective-C a “loosely-typed” or possibly even “untyped” language.

This means that the type you declare for a pointer doesn’t matter one whit at runtime. What matters is what messages you send and to what classes/objects.

All of these calls give you a pointer to a Person object called ‘p’: Person *p = [[Person alloc] init]; Employee *p= [[Person alloc] init]; NSString *p = [[Person alloc] init]; id p = [[Person alloc] init]; although the middle two may throw compiler warnings depending on your build settings.

All of these calls will give you a pointer to an NSString instance called ‘p’: Person *p = [[NSString alloc] init]; Employee *p= [[NSString alloc] init]; NSString *p = [[NSString alloc] init]; id p = [[NSString alloc] init]; although the top two may throw warnings in this case.

See where I’m headed? The type of the pointer declaration is nothing more than a hint to the compiler (and to anyone who reads your code). What matters when your application actually runs is that (in the first example) you’re sending a message to the Person class asking it for a new instance of itself, and in the second example, you’re sending a message to the NSString class asking the same.

id is the universal pointer, and is the same as “void *”, and gives you a pointer to an object of any type. When you declare: id p = [[NSString alloc] init];
you’re declaring a pointer without giving the compiler any hints about what kind of object it will be pointing at, and then you go and point it at an NSString instance.

Any warnings that you may get when you declare:

Employee *p = [[Person alloc] init];
[/code] or even something like [code]
NSString *p = [[Person alloc] init];

are likely the compiler complaining that it thinks the hint you gave it about the pointer was wrong (rightfully so).

The reason that Employee *p = [[Person alloc] init]; may give you a warning but Person *p = [[Employee alloc] init]; doesn’t, is that the Employee class is a subclass of the Person class, so a newly-instantiated Employee instance also knows what it means to be a Person, and doesn’t mind being referred to as one.