An object is polymorphic when its specific type may vary.
The types a specific value may take, is called class.

It is trivial to copy an object if its type is known:

int x;
int y = x;
Here x is not polymorphic, so y is declared of same type (int) as x.
But if the specific type of x were unknown, then y could not be declared of any specific type.

The task: let a polymorphic object contain an instance of some specific type S derived from a type T.
The type T is known.
The type S is possibly unknown until run time.
The objective is to create an exact copy of such polymorphic object (not to create a reference, nor a pointer to).
Let further the type T have a method overridden by S.
This method is to be called on the copy to demonstrate that the specific type of the copy is indeed S.

@interface T : NSObject
- (void)identify;
@end
 
@implementation T
- (void)identify {
    NSLog(@"I am a genuine T");
}
- (id)copyWithZone:(NSZone *)zone {
    T *copy = [[[self class] allocWithZone:zone] init]; // call an appropriate constructor here
                                                        // then copy data into it as appropriate here
                                                        // make sure to use "[[self class] alloc..." and
                                                        // not "[T alloc..." to make it polymorphic
    return copy;
}
@end
 
@interface S : T
@end
 
@implementation S
- (void)identify
{
    NSLog(@"I am an S");
}
@end
 
int main()
{
    @autoreleasepool {
 
        T *original = [[S alloc] init];
        T *another = [original copy];
        [another identify]; // logs "I am an S"
 
    }
    return 0;
}