MST

星途 面试题库

面试题:Objective-C中类方法与实例方法在多态特性上的表现及应用场景

在Objective-C面向对象编程中,多态是重要特性。请分析类方法和实例方法在多态方面的不同表现,结合实际应用场景,说明何时使用类方法的多态,何时使用实例方法的多态,并举出代码示例。
24.4万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

类方法和实例方法在多态方面的不同表现

  1. 类方法
    • 类方法属于类本身,不是属于类的实例。在多态中,类方法的多态基于类的继承体系。当子类继承父类并实现与父类相同的类方法时,通过父类指针调用该类方法,实际执行的是父类的类方法;只有通过子类指针调用时,才会执行子类的类方法。
    • 例如,假设有一个父类 Animal 和子类 Dog,都有类方法 makeSound
  2. 实例方法
    • 实例方法属于类的实例。在多态中,实例方法的多态通过动态绑定实现。当一个父类指针指向子类实例时,调用该实例方法,实际执行的是子类重写后的实例方法。这是Objective - C多态的核心表现,允许通过相同的接口调用不同实现的方法。

何时使用类方法的多态

  1. 应用场景
    • 当需要执行与类本身相关的操作,而不是与特定实例相关的操作时,使用类方法的多态。例如,创建对象的工厂方法,不同子类可以通过类方法创建不同类型的对象。
  2. 代码示例
#import <Foundation/Foundation.h>

@interface Shape : NSObject
+ (instancetype)createShape;
@end

@implementation Shape
+ (instancetype)createShape {
    return [[self alloc] init];
}
@end

@interface Circle : Shape
+ (instancetype)createShape;
@end

@implementation Circle
+ (instancetype)createShape {
    return [[self alloc] init];
}
@end

@interface Rectangle : Shape
+ (instancetype)createShape;
@end

@implementation Rectangle
+ (instancetype)createShape {
    return [[self alloc] init];
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class shapeClass = [Circle class];
        Shape *circle = [shapeClass createShape];
        shapeClass = [Rectangle class];
        Shape *rectangle = [shapeClass createShape];
    }
    return 0;
}

何时使用实例方法的多态

  1. 应用场景
    • 当需要根据对象的具体类型执行不同行为时,使用实例方法的多态。比如在游戏开发中,不同角色类(如战士、法师等)继承自一个基类 Character,每个角色有不同的攻击行为,通过实例方法的多态来实现。
  2. 代码示例
#import <Foundation/Foundation.h>

@interface Character : NSObject
- (void)attack;
@end

@implementation Character
- (void)attack {
    NSLog(@"Character attacks in a general way.");
}
@end

@interface Warrior : Character
- (void)attack;
@end

@implementation Warrior
- (void)attack {
    NSLog(@"Warrior attacks with a sword.");
}
@end

@interface Mage : Character
- (void)attack;
@end

@implementation Mage
- (void)attack {
    NSLog(@"Mage casts a spell.");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Character *character1 = [[Warrior alloc] init];
        Character *character2 = [[Mage alloc] init];
        [character1 attack];
        [character2 attack];
    }
    return 0;
}