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
    
  • 相关阅读:
    浏览器渲染页面
    递归求1-100之和
    border属性
    ES6 Class
    数组去重
    get、post请求
    对象冒充继承
    原型链继承
    实现JS数据拷贝
    【转】centos升级curl版本
  • 原文地址:https://www.cnblogs.com/sublimter/p/4162603.html
Copyright © 2011-2022 走看看