zoukankan      html  css  js  c++  java
  • OC语言--继承、点语法、类别

    1 继承

    1.0 面向对象的三个基本特征:1.封装2.继承3.多态

    1.1 生活中的继承

    -》继承的生活逻辑

    a.继承遗产:预先给予,不需要自行再建

    b.      人类         父类

    男人和女人       子类

    乔布斯 和章子怡     对象

    -》继承的概念:继承(也被称为派生)。

    父类拥有的属性和方法,子类直接获得,这个过程叫做继承。

    子类在父类基础上,衍生出了自己独有的属性和方法,称为派生。

    -》父子类的各种称呼:

    父类   parentClass    超类 supperClass   基类baseClass

    子类   childClass        子类 subClass         派生类derivedClass

    1.2 代码中的继承

    -》继承的基本语法

    a.语法形式

    @interface 子类名 : 父类名

    @interface Person :NSObject//在oc中任何一个类都必须继承一个类,也就是说,每个必须单继承

    @end

    b.继承之后

    子类可以使用父类的所有方法  

    子类可以获得父类非私有的成员变量

    c.类字段和成员方法访问控制

                    @interface Person : NSObject//NSObject 根类
    		{
    			@protected//受保护的:,
    							// 子类继承父类之后,
    							// 子类可以直接使用父类的受保护成员变量
        			int _age;
    			@public//公有的:类内和类外的函数 
    						//都可以直接使用公有的成员变量
    						//这将一定程度上破坏对象信息的隐藏性
        			int _height;
    			@private//私有的:  类内减方法可以直接使用私有的
    						// 类外的方法不能直接使用,
    						// 但是可以通过实例方法间接访问和使用,
    						// 子类继承父类之后,
    						// 子类可以通过父类的方法间接使用父类私有的变量
       				int _money;
    		}
    

    成员方法:没有@private @protected @public 这样的访问控制

    OC中子类继承父类之后就拥有了父类的方法

    注:

    1、OC中的方法类似于C++中的虚函数

    2、OC中是没有类似于C++的private作用域的私有方法,

    但是可以通过其他方式实现

    -》继承在内存中的体现

    子类继承父类之后 子类对象的构成:

    a.继承的父类的成员变量

    b.子类自己特有的成员变量

    -》重写(Override覆盖)

    a.子类从父类继承的方法,有时候不适合子类,子类可以重写这个方法

    b.重写就是重新实现一遍父类的方法(方法名一样 实现内容不同)

    c.子类重写父类方法之后,子类对象最终执行的是子类重写之后的方法

    -》多态

    a.其实多态就是指,同一个接口不同的实现//重写

    b.从OC消息机制看:给不同的对象发送相同的消息,反应不同

    -》什么时候使用继承  

    a.创建大量相似的类

    【例】创建象棋中的棋子,车马士象炮。

    可以先创建棋子类,作为父类。

    b.继承一个官方类,添加属性和方法,创建一个更符合当前工程的新类。

    c.用继承方式统一接口(不常用)

    -》继承的作用   

    代码重复利用,节约资源提高效率

    -》类簇

    a.类簇是基础框架中一种常见的设计模式,基于抽象工厂模式的思想。

    它将若干相关的私有具体工厂子类集合到抽象超类之下;

    b.类簇将一些私有的、具体的子类组合在一个公共的、抽象的超类下面,

    以这种方法来组织类可以简化一个面向对象框架的公开架构,

    而又不减少功能 的丰富性;

    c.NSString NSArray NSDictionary NSNumber都是[类簇/工厂类]

    不能被继承,即使被继承,也不能使用父类的方法。

    2 点语法和属性关键词@property 的使用

    -》点语法与setter/getter 的关系

    点语法和@property 关键字的使用,

    是对于setter/getter方法的语法替代;

    其原理,类似 C 语言中的,是在程序的编译阶段被替代。

    该替代,为文本替代,不去检查程序的逻辑语义。

    a.只要一个类有符合要求的setter/getter方法那么就可以使用'.'操作

    b.xiaohong.name = @"xiaohong"; 这里实际上调用的是setter方法

    NSString *nameString = xiaohong.name;这里实际上调用的是getter方法

    c. id 类型不能直接使用点操作(需要强制类型转换)

    -》属性@property

    a. @property自动声明setter和getter方法

        @synthesize自动实现setter和getter方法

    b.  @property NSUInteger x;创建下述两个方法

    - (void)setX:(NSUInteger)x;

    - (NSUInteger)x;

    @synthesize x = _x;//实现下述两个方法 Xcode4.6以后可以省略

    - (void)setX:(NSUInteger)x

    {

        _x = x;

    }

    - (NSUInteger)x

    {

        return _x;

    }

    -》属性修饰符

    //只读修饰符

    //只有getter方法,没有setter方法

    @property (readonly) NSString * name;

    //直接赋值修饰符(缺省)

    @property (assign) NSString * name;

    //读写修饰符(缺省)

    //同时创建set方法和get方法

    @property (readwrite) NSString * address;

    //原子操作修饰符(缺省)

    @property (atomic) NSString * group;

    //非原子操作

    @property (nonatomic) NSString * grade;

    //多个属性修饰符,需要用逗号隔开

    @property (nonatomic, readonly, getter = birth) NSString * birthDay;

    //给set方法和get方法起别名

    @property (getter = personAge, setter = setAgi:) int age;

    3. 类别/类目 Category

    (1)增补既有类的方法,它是具名

    (2)不能添加新的属性

    (3)包括NSString,NSDictionary,NSArray,NSNumber内所有的类都能扩展,都能使用category

    -》类别的基本语法

    //类别的声明部分
    
    @interface  NSString(Print)
    
    -(void)print;//增加的新方法(不能有成员变量的声明)
    
    ...
    
    @end
    
     
    
    //类别实现部分
    
    @implementation NSString(Print)
    
    -(void)print{
    
     
    
    }
    
    …
    
    @end
    

    注:一旦使用类别给已有的类增补方法,那么这个类的对象就可以使用这个方法

    -》.类别功能:

      a. 可以给已有/ 系统原生的类增补方法

      b.可以对类的方法进行分类管理,

        可以将类的实现分散到多个不同文件或多个不同框架中。

    -》使用类别需要注意的问题

    a.类别中不能添加成员变量

    b.使用类别增补的方法须导入类别头文件

    c.父类类别中的方法,子类也可以用

    -》类扩展/匿名类别 (class extend)

        当不想对外公开一些类的方法时,我们可以使用类扩展

    a.类扩展的基本语法

    类扩展的声明写在.m文件中

      

    @interface Person()//没有名字
    
      - (void)song;
    
    @end
    
     
    @implementation Person
    
    - (void)song{
    
    NSLog(@"hello");
    
    }
    
    @end
    

    注:

    类扩展只有声明部分,没有实现部分 。

    类扩展中声明的方法需要在类的实现部分实现

    b.类扩展的功能

    1.可以实现私有方法

    2.方便程序员调用不公开的方法

    3.可以声明成员变量

     

    eg.示例代码

    Account.h文件

    #import <Foundation/Foundation.h>
    #define RATE 0.0325
    @interface Account : NSObject{
      NSUInteger _uid;//用户账号
      NSString* _upasswd;//用户密码
      double _uamount;//账户余额
      double _uperiod;//储蓄时间
      double _rate;//一年期的存款利率
    }
    @property (assign,nonatomic) NSUInteger uid;
    @property (copy,nonatomic) NSString* upasswd;
    @property (assign,nonatomic) double uamount;
    @property (assign,nonatomic) double uperiod;
    @property (assign,nonatomic) double rate;
    - (void)deposit:(double)money;//存款
    - (double)withdraw:(double)money;//提款
    - (double)settlementOnWithdraw:(double)money;//取款时结算利息
    - (double)settlementUponYear;//年度结算利息
    - (double)interestCaculate;//利息计算
    - (double)incomeCaculate;//到期本息收益
    + (void)testBySelf;//本类的自测方法
    - (id)initWithUid:(NSUInteger)aUid andUpasswd:(NSString*)aUpasswd andUamount:(double)aUamount;
    
    @end
    

    Account+currency.h文件

    #import "Account.h"
    
    @interface Account (currency)
    - (void)deposit:(double)money withForeignCurrency:(char)type;//存款
    - (double)withdraw:(double)money withForeignCurrency:(char)type;//提款
    @end
    

    Account.m文件

    #import "Account.h"
    #import "Account+currency.h"
      //#include "Account_dollar.h"
    
    @implementation Account
    @synthesize uid=_uid;
    @synthesize uamount=_uamount;
    @synthesize upasswd=_upasswd;
    @synthesize rate=_rate;
    @synthesize uperiod=_uperiod;
    
    - (void)deposit:(double)money{
      _uamount += money;
      NSLog(@"存款后的当前账户余额:%.2lf",_uamount);
    }
    
    - (double)withdraw:(double)money{
      _uamount += [self settlementOnWithdraw:_uamount];
      _uamount -= money;
      NSLog(@"取款后的当前账户余额:%.2lf",_uamount);
      return _uamount;
    }
    - (double)settlementOnWithdraw:(double)money//取款时结算利息
    {
      double RetMoney = money;
      
      return RetMoney *= (_rate * _uperiod);
    }
    - (double)settlementUponYear//年度结算利息
    {
      
      return _uamount *= (1+_rate);
    }
    - (double)interestCaculate//到期利息计算
    {
      double interest = 0.0;
      
      return interest = _uamount * _rate;
    }
    - (double)incomeCaculate//到期本息收益
    {
      double income = 0.0;
    
      return income = _uamount*(1+_rate);
    }
    + (void)testBySelf//本类的自测方法
    {
        //新建一个账户实例
      Account* aAccount = [[Account alloc]init];
        //显示账户初始状态
      NSLog(@"%@",aAccount);
        //存款测试
      [aAccount deposit:100.00];
      NSLog(@"%@",aAccount);
        //模拟的日期间隔
      int n = 36;
      for(int i=1;i<=n;i++){
        aAccount.uperiod = (double)i/(double)365;
      }
    
        //取款测试
      [aAccount withdraw:50.00];
      NSLog(@"%@",aAccount);
        //模拟存一笔前,并到一年期
      [aAccount deposit:100.00];
        //模拟时间流逝
      for(int i=n;i<=365;i++){
        aAccount.uperiod = (double)i/(double)356;
      }
      [aAccount settlementUponYear];
       NSLog(@"%@",aAccount);
        //外币存款
    //  aAccount.foreign_amount = 1.0;
      [aAccount deposit:200.00 withForeignCurrency:'$'];
      
    }
    - (id)initWithUid:(NSUInteger)aUid andUpasswd:(NSString*)aUpasswd andUamount:(double)aUamount{
      if (self = [super init]) {
        _rate = RATE;
        _uperiod = 1/365;
        _uid = aUid;
        _upasswd = aUpasswd;
        _uamount = aUamount;
      }
      
      return self;
    }
    -(id)init
    {
      return [self initWithUid:1 andUpasswd:@"123456" andUamount:1.0];
    }
    - (NSString *)description
    {
      NSString* passwd_des = @"******";
      
      return [NSString stringWithFormat:@"用户账号:%06lu 用户口令:%@ 账户余额:%.2lf(元) 当前定期存款利率(一年期):%.4lf 存储时间:%.2lf(年)", _uid,passwd_des,_uamount,_rate,_uperiod];
    }
    @end
    

    Account+currency.m文件

    #import "Account+currency.h"
    #import "Account_dollar.h"
    
    @implementation Account (currency)
      //外币存款方法
    - (void)deposit:(double)money withForeignCurrency:(char)type//存款
    {
      double fa = self.foreign_amount;
      fa += money;
      self.foreign_amount = fa;
      NSLog(@"存款后的当前外币(%c)账户余额:%.2lf",type,self.foreign_amount);
    }
      //外币取款方法有 bug,请自行修改正确!!!
    - (double)withdraw:(double)money withForeignCurrency:(char)type//提款
    {
      self.foreign_amount += [self settlementOnWithdraw:self.foreign_amount];
      self.foreign_amount -= money;
      NSLog(@"取款后的当前外币(%c)账户余额:%.2lf",type,self.foreign_amount);
      return self.foreign_amount;
    }
    
    
    @end
    

    Account_dollar.h文件

    #import "Account.h"
    
    @interface Account (){
      char _currency_type;
      double _foreign_rate;
      double foreign_amount;
    }
    @property (assign) char currency_type;
    @property (assign) double foreign_rate;
    @property (assign) double foreign_amount;
    
    @end
    
  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/sublimter/p/4162603.html
Copyright © 2011-2022 走看看