zoukankan      html  css  js  c++  java
  • [objective-c] 02

    简介

    本章教程主要讨论OC的继承语法以及类的复合编程模式。

    1. OC继承语法
    2. OC语言的动态特性
    3. OC的复合模式
    4. super关键字

    1.OC继承语法

    OC语法只支持单根继承,即一个类只能有一个父类。

    继承关键字为:

    @interface 类目 : 父类名
    

    例如我们昨天声明的三角形类

    @interface Triangle : NSObject
    
    @end
    

    表示Triangle类是继承自NSObject类。Triangle是NSObject的子类,NSObject是Triangle的父类。

    OC语法中规定,通过继承方式,可以继承父类的所有方法和除私有权限以外的所有成员变量。

    例如上一章的三角形类

    @interface Triangle : NSObject
    
    @property double a;
    @property double b;
    @property double c;
    
    -(instancetype)initWithA:(double)a B:(double)b C:(double)c;
    -(double)area;
    
    @end
    
    @implementation Triangle
    
    - (instancetype)initWithA:(double)a B:(double)b C:(double)c
    {
        self = [super init];
        if (self) {
            self.a = a;
            self.b = b;
            self.c = c;
        }
        return self;
    }
    
    -(double)area
    {
        double s=(_a+_b+_c)/2;
        return sqrt(s*(s-_a)*(s-_b)*(s-_c));
    }
    
    

    本章我们可以通过继承的方法创建一个新的三角形类

    @interface TriangleSub : Triangle
    
    @end
    
    
    @implementation TriangleSub
    
    @end
    

    可以看到我们新创建的TriangleSub类中没有声明任何方法也没有实现任何方法。但是通过继承语法,我们无偿获得了父类的所有方法和成员变量。

    TriangleSub * subT = [[TriangleSub alloc] initWithA:10 B:11 C:12];
    double s = [subT area];
    NSLog(@"s = %g",s); // NSLog函数是OC中向控制台输出信息的函数
    

    2.OC语言的动态特性

    OC语言是动态类型语言,其表现为调用方法时,不会依据对象指针类型调用对象方法,而根据对象指针使用的内存类型调用响应的方法。

    下面通过代码描述这个特性。

    首先我们创建一个测试类TestClass

    @interface TestClass : NSObject
    
    -(void)test;
    
    @end
    
    @implementation TestClass
    
    -(void)test
    {   
        NSLog(@"这里是TestClass类的test方法");
    }
    @end
    

    我们继续创建两个类:

    SubA继承自TestClass

    @interface SubA : TestClass
    
    
    @end
    
    @implementation SubA
    
    //重写父类的方法
    -(void)test
    {   
        NSLog(@"这里是SubA类的test方法");
    }
    @end
    

    SubB继承自TestClass

    @interface SubB : TestClass
    
    @end
    
    @implementation SubB
    
    //重写父类的方法
    -(void)test
    {   
        NSLog(@"这里是SubB类的test方法");
    }
    @end
    

    现在做如下测试

    SubA * a = [[SubB alloc] init];
    [a test]; // 这样调用没有编译错误,符合OC的语法规则,那会输出哪个结果。
    

    根据我们之前讲的,OC的动态特性的表现形式

    对象指针在调用方法时,不会根据对象指针类型调用响应方法,而是根据对象指针指向的内存类型调用响应的方法

    由此可见,对象指针a的类型为SubA类型,但其指向的内存类型为SubB类型。所以用对象指针调用test方法时,会调用SubB的test方法。

    其输出结果为:这里是SubB类的test方法。

    由于OC语法动态特性的原因,在编写代码的过程中,对象指针类型只在编译时起作用。在运行过程中没有任何影响。

    OC语法推出一个id关键字,表示在编译过程中不指定类型。

    使用id类型编写代码对运行不会有任何影响。但在IDE环境中,便无法开启代码自动补全功能,因IDE工具并不知道该对象指针是什么类型,所以无法进行代码自动提示和补全。

    3.OC的复合模式

    在OC的复合模式就是把其他对象作为自身的一部分,以提升自身的功能。

    比如我现在要制作一台电脑,电脑需要CPU,显示器,鼠标和键盘等。这些东西的研发都是很复杂的过程。如果现在有成型的CPU等组件,就可以直接用这些组件攒一台电脑。复合模式就是这样。

    所以我们在制作电脑前要先找到这些组件。这些组件并不需要我们来制作,有专业的公司提供这些成型的组件。

    在本章练习的SDK中提供了如下组件。

    KeyBoard    键盘类
    BigMouse    鼠标类
    Monitor     显示器类
    IntelCPU    CPU类
    

    下面就用SDK中提供的各种组件来快速制作一台电脑。

    首先我们进行电脑类的声明。需要使用的组件都声明成属性,作为电脑类的一部分。

    @interface Computer : NSObject
    
    @property(strong, nonatomic) KeyBoard *aKeyBoard;
    @property(strong, nonatomic) BigMouse *aMouse;
    @property(strong, nonatomic) Monitor  *aMonitore;
    @property(strong, nonatomic) IntelCPU *aCPU;
    
    @end
    
    

    在这里我们先补充一下属性括号中的内容。

    属性括号中的内容为属性控制符,分别对属性的读写权限,内存管理和线程操作做出相关规定。

    1. 读写权限由两个关键字控制,分别为:readonlyreadwrite。其中如果不写默认为readwrite。通常属性的读写权限都为可读可写。
    2. 内存管理权限由四个关键字控制,分别为:assgin,strong,weakcopy。如果不写,默认为assgin。如果属性类型为基本数据类型,那么只能用assgin。如果属性类型为对象指针,一般情况下用strong,特殊情况下用weakcopy。特殊情况在后面的内存管理章节会展开讲解。
    3. 线程操作权限由两个关键字控制,分别为:atomicnonatomic。其中如果不写默认为atomic。通常我们使用nonatomic作为线程操作,其具体内容在后续的多线程章节会展开讲解。

    然后继续实现电脑类,因CPU等组件是电脑的一部分,所以我们需要重新电脑的初始化方法,在电脑初始化的的同时也初始化各种组件,为其分配内存。

    @implementation Computer
    
    - (instancetype)init
    {
        self = [super init];
        if (self) 
        {
            self.aKeyBoard = [[KeyBoard alloc] init];
            self.aMouse = [[BigMouse alloc] init];
            self.aMonitore = [[Monitor alloc] init];
            self.aCPU = [[IntelCPU alloc] init];
        }
        return self;
    }
    
    @end
    
    

    经过声明组件属性,为组件的对象指针分配内存。我们就使用成型的组件快速的制作好了一个功能完整的电脑。

    4.super关键字

    通常继承和复合会一同使用,来快速构造一个复杂的对象。

    例如现在有一个需求,要求我们快速制作一个可以除甲醛的高级空调。通常我们并不是从零开始研发,而是基于一定基础开始制作。

    在这里,我提供了两个对象作为研发的基础

    1. Kongtiao类,具有制冷方法
    2. ChuJiaquan类,具有除甲醛的方法

    以下是Kongtiao类的声明

    @interface Kongtiao : NSObject
    
    -(void)zhiling;
    
    @end
    

    以下是ChuJiaquan类的声明

    @interface ChuJiaQuan : NSObject
    
    -(void)chuJQ;
    
    @end
    

    首先明确我们制作的是一个空调,所有我们创建一个高级空调类继承自空调类。

    然后高级空调需要有除甲醛的功能,我们通过复合模式,把除甲醛的模块作为高级的空调的一部分。

    最后我们重写父类的制冷方法,在制冷过程中添加除甲醛的步骤。但是在重写的方法中会覆盖掉父类原有的方法,所以这里我们需要在重写方法中手动调用父类原始方法。就需要用到super关键字。

    @interface NewKongtiao : Kongtiao
    
    @property(strong, nonatomic) ChuJiaQuan * cJQ;
    
    @end
    
    @implementation NewKongtiao
    
    - (instancetype)init
    {
        self = [super init];
        if (self) 
        {
            self.cJQ = [[ChuJiaQuan alloc] init];
        }
        return self;
    }
    -(void)zhileng
    {
        [super zhileng];
        [self.cJQ chuJQ];
    }
    
    @end
    
    

    这样我们在使用高级空调制冷的同时,也同时能够除甲醛了。

  • 相关阅读:
    洛谷 P1474 货币系统 Money Systems 题解
    洛谷 P5146 最大差值 题解
    洛谷 P1880 [NOI1995]石子合并 题解
    洛谷 P1063 能量项链 题解
    洛谷 P3385 【模板】负环 题解
    洛谷 P1522 牛的旅行 Cow Tours 题解
    洛谷 P2212 [USACO14MAR]浇地Watering the Fields 题解
    浅谈 C 语言中模块化设计的范式
    内联函数(Inline Functions)
    C++中全局变量的声明和定义
  • 原文地址:https://www.cnblogs.com/lqios/p/4264180.html
Copyright © 2011-2022 走看看