Objective-C 继承

  • 继承

    面向对象编程中最重要的概念之一就是继承。继承允许我们用另一个类来定义一个类,这使得创建和维护应用程序变得更加容易。这也提供了重用代码功能和快速实现时间的机会。创建类时,程序员可以指定新类应继承现有类的成员,而不必编写全新的数据成员和成员函数。此现有类称为基类,而新类称为派生类。继承的概念实现了一种关系。例如,哺乳动物是一种动物,狗是哺乳动物,以及狗是一种动物等等。
  • 基础和派生类

    Objective-C仅允许多级继承,即,它只能具有一个基类,但允许多级继承。Objective-C中的所有类均源自超类NSObject。
    
    @interface derived-class: base-class
    
    考虑如下基类Person及其派生类Employee-
    
    #import <Foundation/Foundation.h>
     
    @interface Person : NSObject {
       NSString *personName;
       NSInteger personAge;
    }
    
    - (id)initWithName:(NSString *)name andAge:(NSInteger)age;
    - (void)print;
    
    @end
    
    @implementation Person
    
    - (id)initWithName:(NSString *)name andAge:(NSInteger)age {
       personName = name;
       personAge = age;
       return self;
    }
    
    - (void)print {
       NSLog(@"Name: %@", personName);
       NSLog(@"Age: %ld", personAge);
    }
    
    @end
    
    @interface Employee : Person {
       NSString *employeeEducation;
    }
    
    - (id)initWithName:(NSString *)name andAge:(NSInteger)age 
      andEducation:(NSString *)education;
    - (void)print;
    @end
    
    @implementation Employee
    
    - (id)initWithName:(NSString *)name andAge:(NSInteger)age 
       andEducation: (NSString *)education {
          personName = name;
          personAge = age;
          employeeEducation = education;
          return self;
       }
    
    - (void)print {
       NSLog(@"Name: %@", personName);
       NSLog(@"Age: %ld", personAge);
       NSLog(@"Education: %@", employeeEducation);
    }
    
    @end
    
    int main(int argc, const char * argv[]) {
       NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];        
       NSLog(@"Base class Person Object");
       Person *person = [[Person alloc]initWithName:@"Raj" andAge:5];
       [person print];
       NSLog(@"Inherited Class Employee Object");
       Employee *employee = [[Employee alloc]initWithName:@"Raj" 
       andAge:5 andEducation:@"MBA"];
       [employee print];        
       [pool drain];
       return 0;
    }
    
    编译并执行上述代码后,将产生以下结果-
    
    2020-08-20 10:17:53.583 helloWorld[7264:2884] Base class Person Object
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Name: Raj
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Age: 5
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Inherited Class Employee Object
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Name: Raj
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Age: 5
    2020-08-20 10:17:53.589 helloWorld[7264:2884] Education: MBA
    
  • 访问控制和继承

    如果派生类在接口类中定义,则可以访问其基类的所有私有成员,但不能访问在实现文件中定义的私有成员。
    我们可以根据谁可以通过以下方式访问它们来总结不同的访问类型:派生类继承所有基类方法和变量,但以下情况除外:
    • 使用扩展名在实现文件中声明的变量是不可访问的。
    • 使用扩展名在实现文件中声明的方法不可访问。
    • 如果继承的类实现了基类中的方法,则执行派生类中的方法。