OC基础--继承

继承的基本概念:

  现实生活中的继承:

  人类是一个基类(也称做父类),通常情况下所有人类所共同具备的特性,如有手有脚能吃能喝

  按照生活常规,我们继续给人类来细分的时候,我们可以分为学生类 工人类等,学生类和工人类同样具备手 脚 吃 喝等特性,而这些特性是所有人类所共有的,那么就可以让学生或工人类继承人类,这样当建立学生类和工人类的时候我们无需再定义人类中已经有的成员和方法,而只需要描述学生类和工人类所特有的特性即可。

  学生类和工人类的特性是由在人类原有特性基础上增加而来的,那么学生类和工人类就是人类的派生类(也称做子类)。以此类推,层层递增, 这种子类获得父类特性的概念就是继承

OC中的继承关系

  • B类继承A类,那么B类将拥有A类的所有属性和方法,此时我们说A类是B类的父类,B类是A类的子类
  • C类继承B类,那么C类将拥有B类中的所有属性和方法,包括B类从A类中继承过来的属性和方法,此时我们说B类是C类的父类,C类是B类的子类
  • 注意:
    • 基类的私有属性能被继承,不能在子类中访问。
    • OC中的继承是单继承:也就是说一个类只能一个父类,不能继承多个父类
    • 子类与父类的关系也称为isA(是一个)关系,我们说 子类isA父类,也就是子类是一个父类,比如狗类继承动物类,那么我们说狗isA动物,也就是狗是一个动物。再如汽车继承交通工具,那么们说汽车isA交工工具,也就是汽车是一个交通工具
    • 继承的合理性:引用《大话西游》里的一句话来描述继承的合理性。“人是人他妈生的,妖是妖他妈生的!” 以此类推 人妖是….

继承是代码重用的重要方式之一

  • 来感受一下,  我们定义个学生类和一个工人类  如果不使用继承,  代码如下:

    学生类声明文件.h:

      #import <Foundation/Foundation.h> 

      @interface Student : NSObject
      {
          // 姓名
          NSString * _name;
          // 年龄
          int _age;
          // 学号
          int _studengNO;
          // 身份
          NSString * _identity;
      }
      - (void) setName:(NSString *) name;
      - (NSString *) name;
      - (void) setAge: (int) age;
      - (int) age;
      - (void) setStudentNO: (int) studentNO;
      - (int) studentNO;
      - (void) setIdentity: (NSString *) identity;
      - (NSString *) identity;
      // 吃
      - (void) eat;
      // 学习
      - (void) study;
      @end

    学生类实现文件.m:

            #import "Student.h" 

            @implementation Student
            - (void)setName:(NSString *)name{
                _name = name;
            }
            - (NSString *)name{
                return _name;
            }
            - (void)setAge:(int)age{
                _age = age;
            }
            - (int)age{
                return _age;
            }
            - (void)setStudentNO:(int)studentNO{
                _studengNO = studentNO;
            }
      - (int)studentNO{
          return _studengNO;
      }
      - (void)setIdentity:(NSString *)identity{
          _identity = identity;
      }
      - (NSString *) identity{
          return _identity;
      }
      // 吃
      - (void)eat{
          NSLog(@"吃东西");
      }
      // 学习
      - (void)study{
          NSLog(@"学习");
      }
      @end           

    工人类声明文件.h:

      #import <Foundation/Foundation.h> 

      @interface Worker : NSObject
      {
          // 姓名
          NSString * _name;
          // 年龄
          int _age;
          // 工号
          int _workNO;
          // 身份
          NSString * _identity;
      }
      - (void) setName: (NSString *) name;
      - (NSString *) name;
      - (void) setAge: (int) age;
      - (int) age;
      - (void) setWorkNO: (int) workNO;
      - (int) workNO;
      - (void) setIdentity: (NSString *) identity;
      - (NSString *) identity;
      // 吃
      - (void) eat;
      // 学习
      - (void) study;
      // 工作
      - (void) work;
      @end

    工人类实现文件:

      #import "Worker.h"

       @implementation Worker
      - (void)setName:(NSString *)name{
          _name = name;
      }
      - (NSString *)name{
          return _name;
      }
      - (void)setAge:(int)age{
          _age = age;
      }
      - (int)age{
          return _age;
      }
      - (void)setWorkNO:(int)workNO{
          _workNO = workNO;
      }
      - (int)workNO{
          return _workNO;
      }
      - (void)setIdentity:(NSString *)identity{
          _identity = identity;
      }
      - (NSString *) identity{
          return _identity;
      }
      // 吃
      - (void)eat{
          NSLog(@"吃东西");
      }
      // 学习
      - (void)study{
          NSLog(@"学习");
      }
      // 工作
      - (void)work{
          NSLog(@"上班了 干活");
      }
      @end

  比较一下上面的代码   看看有多少是重复的:

    声明文件中重复部分:

      属性:

          // 姓名
          NSString * _name;
          // 年龄
          int _age;
          // 身份
          NSString * _identity;

      行为:

        - (void) setName:(NSString *) name;
        - (NSString *) name;
        - (void) setAge: (int) age;
        - (int) age;
        - (void) setIdentity: (NSString *) identity;
        - (NSString *) identity;
        // 吃
        - (void) eat;
        // 学习
        - (void) study; 

    实现文件中重复部分:

        - (void)setName:(NSString *)name{
            _name = name;
        }
        - (NSString *)name{
            return _name;
        }
        - (void)setAge:(int)age{
            _age = age;
        }
        - (int)age{
            return _age;
        }
        - (void)setIdentity:(NSString *)identity{
            _identity = identity;
        }
        - (NSString *) identity{
            return _identity;
        }
        // 吃
        - (void)eat{
            NSLog(@"吃东西");
        }
        // 学习
        - (void)study{
            NSLog(@"学习");
        } 

  得到的结果是:

    学生类中就一个学号在工人类中没有

    工人类中就一个工号和一个工作的行为在学生类中没有

    其余部分都是重复代码

    如果还要添加几个其他类:  如学前期的幼儿类    退休后的老人类等等   那么上面那些重复的代码还得重复好几遍   复制粘贴都感觉累有木有

现在我们来添加一个Person类   人类中定义属性有 姓名 (name) 年龄(age)  身份(identity)  行为有 吃(eat) 学习(study)

使用继承关系后再来看看代码:

  Person类声明文件:

    #import <Foundation/Foundation.h>

    @interface Person : NSObject
    {
        // 姓名
        NSString * _name;
        // 年龄
        int _age;
        // 身份
        NSString * _identity;
    }
    - (void) setName:(NSString *) name;
    - (NSString *) name;
    - (void) setAge: (int) age;
    - (int) age;
    - (void) setIdentity: (NSString *) identity;
    - (NSString *) identity;
    // 吃
    - (void) eat;
    // 学习
    - (void) study;
    @end

  Person类实现文件:

    #import "Person.h"

    @implementation Person
    - (void)setName:(NSString *)name{
        _name = name;
    }
    - (NSString *)name{
        return _name;
    }
    - (void)setAge:(int)age{
        _age = age;
    }
    - (int)age{
        return _age;
    }
    - (void)setIdentity:(NSString *)identity{
        _identity = identity;
    }
    - (NSString *) identity{
        return _identity;
    }
    // 吃
    - (void)eat{
        NSLog(@"吃东西");
    }
    // 学习
    - (void)study{
        NSLog(@"学习");
    }
    @end

  学生类声明文件:

    #import <Foundation/Foundation.h>
    #import "Person.h" 

    @interface Student : Person
    {
        // 学号
        int _studengNO;
    }
    - (void) setStudentNO: (int) studentNO;
    - (int) studentNO;
    @end

  学生类实现文件:

    #import "Student.h"

    @implementation Student
    - (void)setStudentNO:(int)studentNO{
        _studengNO = studentNO;
    }
    - (int)studentNO{
        return _studengNO;
    }
    @end

  工人类的声明文件:

    #import <Foundation/Foundation.h>
    #import "Person.h"
  
    @interface Worker : Person
    {
        // 工号
        int _workNO;
    }
    - (void) setWorkNO: (int) workNO;
    - (int) workNO;
    // 工作
    - (void) work;
    @end

  工人类的实现文件:

    #import "Worker.h"

    @implementation Worker
    - (void)setWorkNO:(int)workNO{
        _workNO = workNO;
    }
    - (int)workNO{
        return _workNO;
    }
    // 工作
    - (void)work{
        NSLog(@"上班了 干活");
    }
    @end 

  好了, 现在再来看看代码: 我们的代码中多了一个Person类的声明和实现文件   在这个类中声明定义的就是我们之前学生类和工人类中重复的那一部分.

  "B类继承A类,那么B类将拥有A类的所有属性和方法" 就是说如果 我们让学生类和工人类都继承自Person类  , 那么就算我们在学生类中和工作类中都没有声明那些姓名 年龄 吃 学习之类的属性和方法,  这两个类也能从Person类中得到这些行为属性.  而在学生类中只需要声明学生类特有的学号属性, 工人类中只需要声明工人类特有的工号,工作这种特有的行为属性即可,  这样子在学生类和工人类中得代码看起来简洁了很多, 而且以后如果我们需要再添加什么婴儿类  老人类, 也只需要在相关类中添加他们特有的行为属性就行了.

  在这个例子里, Person类就是父类   学生类和工人类就是Person类的子类,  需要注意的是OC也是单继承的,  毕竟咱都只有一个父亲是吧, (呃   那个   干爹不算) ,  在父类中定义的所有行为属性,  子类都能继承过去,  而在子类中还可以添加他特有的行为属性,   也就是说我爸有的 我都有,  我有的, 我爸不一定有(例如: 我会打Dota  我爸不会 ).

  当我们发现两个类中有定义很多重复的行为属性的时候, 便可以把这些重复的部分都抽取出来当一个父类;  继承对代码的重用性和可扩展性 , 看上面例子体会一下吧

OC中继承的实现格式:

  @interface 子类名称 : 父类名称

  @end

    记得导入父类头文件

继承:

当B类继承A类, 那么B类就拥有A类所有的属性和方法(类方法/对象方法)

优点:

提高代码的复用性

可以让类与类之间产生关系, 正是因为继承让类与类之间产生了关系所以才有了多态

  缺点:   增加了代码之间的耦合性

注意:

不要以为继承可以提高代码的复用性, 以后但凡发现多个类当中有重复代码就抽取一个父类

只要满足一定的条件我们才能使用继承

条件: XXXX 是 XXX   /    某某某 is a 某某某    (继承是  ‘是‘ 的关系   接口(协议) 是 ‘有‘ 的关系)

方法的重写:

  • 在子类中实现与父类中同名的方法,称之为方法重写( 方法名相同   方法体不同   子类提供新的实现)
  • 重写以后当给子类发送这个消息的时候,执行的是在子类中重写的那个方法,而不是父类中的方法
  • 如果想在子类中调用被子类重写的父类的方法,可以通过super关键字
  • 使用场景:当从父类继承的某个方法不适合子类,可以在子类中重写父类的这个方法

  方法重写: 子类从父类继承了父类的方法(行为)  但是不想用父类的实现体   可以自己提供新的实现覆盖掉父类的实现

    举例:  我爸会打人   我从我爸那也继承了打人的行为  我爸打人用拳头打    但是我感觉用拳头打不爽   就可以用自己的方式去打 (如用板砖砸)      这样虽然都是打人的方法   但是我用板砖打覆盖了从我爸那继承来的用拳头打     这样方法名相同   但是方法的实现子类和父类不同(子类的实现覆盖了父类的实现)   就是方法的重写

  在上面例子中我们来重写父类学习的方法:

    Person类中得学习方法实现:

    // 学习
    - (void)study{
        NSLog(@"学习");
    }

    工人类重写父类的学习方法:

    // 学习
    - (void)study{
        NSLog(@"我们在职人员通过上网来学习");
    }

    学生类重写父类的方法:

    // 学习
    - (void)study{
        [super study];
        NSLog(@"我们学生都通过去上课来学习");
    } 

继承中方法调用的顺序:

  1、在自己类中找

  2、如果没有,去父类中找

  3、如果父类中没有,就去父类的父类中

  4、如果父类的父类也没有,就还往上找,直到找到基类(NSObject)

  5、如果NSObject都没有就报错了

  以上如果找到了就执行这个方法,就不再往后查找了

继承的注意事项:

  • 子类不能定义和父类同名的成员变量,私有成员变量也不可以;因为子类继承父类,子类将会拥有父类的所有成员变量,若在子类中定义父类同名成员变量 属于重复定义。
  • OC类支持单一继承,不支持多继承;也就是说一个类只能有一个直接父类
  • OC类支持多层继承

super关键字:

  概念: super是个编译器的指令符号,只是告诉编译器在执行的时候,去调谁的方法

  作用:    直接调用父类中的某个方法

       super在对象方法中,那么就会调用父类的对象方法     super在类方法中,那么就会调用父类的类方法

  使用场合:   子类重写父类的方法时想保留父类的一些行为

时间: 2024-10-06 00:12:40

OC基础--继承的相关文章

OC基础:继承.初始化方法,便利构造器

继承: 1.单向继承,一个类只能有一个父类,一个父类可以有多个子类. 2.单向继承,基类(根类)是OSObject 3.子类可以继承父类的属性和方法 当父类的方法不满足子类的需求时,子类可以重写父类的方法,重写父类的方法,在子类中不需要再次声明. 1.完全重写 2.部分重写   使用super 建立继承关系之后,子类可以继承父类的: 1.实例变量,@[email protected]修饰情况之下 2.公开的方法 一个方法如果在.h中声明了,那么这个方法就是公开的方法,如果没有声明,则是私有的.

四.OC基础--1.文档安装和方法重载,2.self和super&amp;static,3.继承和派生,4.实例变量修饰符 ,5.私有变量&amp;私有方法,6.description方法

四.OC基础--1.文档安装和方法重载, 1. 在线安装 xcode-> 系统偏好设置->DownLoads->Doucument->下载 2. 离线安装 百度xcode文档 3. 方法重载: 是指在一个类中定义多个同名的方法 在OC中没有重载 2.self和super&static, self和super: 1. self理解: 谁调用当前方法, self就代表谁. 比如: 在对象方法中,self代表的是对象, 因为只有对象才可以调用对象方法 在类方法中, self代表的

iOS开发OC基础:OC基础概念总结,OC面向对象的思想

一.什么是OOP: OOP(Object Oriented Programming):面向对象编程 二.面向对象和面向过程的区别: 面向过程编程:分析解决问题的步骤,实现函数,依次使用面向对象编程:分解问题组成的对象,协调对象间的联系和通信,解决问题. 面向过程是以事件为中心,关心的是完成这个事件的详细步骤:面向对象是以事物为中心,关心的是事物应该具备的功能,而完成一个事件只是事物所有功能里面的一个小功能(以过程为中心,以对象为中心) 三.类和对象 对象定义了解决问题的步骤中的行为,不刻意完成一

iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误

在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握. expression:表达式assignable:赋值variable:变量redefinition:重复定义type:类型conflicting:冲突项invalid:无效的conversion:转换specifier:说明符indent:缩进operands:运算对象.操作数binary:二

OC基础 代理和协议

OC基础 代理和协议 1.协议 (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法. (2)协议的使用步骤:制定协议-->遵守协议-->实现协议-->调用协议. (3)协议声明的关键字: (a)@required,必须实现,不实现的话在.m文件内会报警告. (b)@optional,可选实现,不实现的话在.m文件内也不会报警告. (4)协议和继承的区别: (a)相同之处:都可以规范统一类中的方法. (b)不同之处:继承的子类不需要再实现一遍父类

OC基础 点语法的使用

OC基础 点语法的使用 1.创建一个Student类继承于NSObject,Student.h文件 #import <Foundation/Foundation.h> @interface Student : NSObject { NSString *_name; NSString *_nickName; } //@property定义属性 //1,它给该类声明了一个属性名+下划线的变量 //2,它给该类声明了一个getter方法和一个setter方法 //修饰符 //atomic和nonat

OC基础(22)

NSMutableString基本概念 NSMutableString常用方法 NSMutableString练习 *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30p

oc基础知识(转)

1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch框架 3.Xcode使用 -------------------- CocoaTouch Media Core Services Core OS -------------------- System Framework OC的类声明,定义域 OC关键字定义为  @class O-C特有的语句for(..in ..)迭代循环,其他的条件和循环语句和c一样 OC对面向对象的概述 (1)

OC基础 类的三大特性

OC基础  类的三大特性 OC的类和JAVA一样,都有三大特性:继承,封装,多态,那么我们就来看一下OC中类的三大特性. 1.继承 继承的特点: (1)子类从父类继承了属性和方法. (2)子类独有的属性和方法不能被父类使用. (3)子类独有的属性和方法,不能够在子类之间互相使用. (4)子类能够重写父类的方法,子类调用该方法时:首先调用子类的方法,如果子类没有该方法,就调用父类的该方法. (5)子类对象指针可以转换成父类对象指针,但是父类对象指针不能够转换成子类对象指针. 三种权限变量的继承: