———————————————————————————————————————————

继承



一段代码:



#import <Foundation/Foundation.h>



@interface Animal : NSObject

{

    int _age;

}

-(void)setAge:(int)age;

-(void)eat:(NSString *)foodName;

-(void)run;

@end



@interface Dog : Animal

-(void)lookHome;

@end



@interface JunDog : Dog

-(void)zhaDiaobao;

@end



@implementation Animal

-(void)setAge:(int)age

{

    _age=age;

}

-(void)eat:(NSString *)foodName

{

    NSLog(@"eat sth. about %@",foodName);

}

-(void)run

{

    NSLog(@"run!!!he is %d years old!!!",_age);

}

@end



@implementation Dog

-(void)lookHome

{

    NSLog(@"lookHome!");

}

@end



@implementation JunDog

-(void)zhaDiaobao

{

    NSLog(@"zhaDiaobao!!");

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

//        JunDog 是 Dog类 的派生类,他虽然没有直接继承于Animal,但是因为Dog继承了Animal,所以JunDog可以调用Animal中的方法和成员变量

        JunDog *jd=[JunDog new];

        

        [jd setAge:3];

        [jd run];

    }

    return 0;

}





//                                                                                                                       该类类名

//继承就两点,①导入父类的头文件  ②在这里后面写上父类名    @interface  className : 父类名 …… @end





———————————————————————————————————————————

基类和派生类之间的关系



派生类方法属性=基类方法和属性+派生类自己新增的方法和属性



注意:

①★★★基类的私有属性能被继承,但是不能访问(@private类型的变量是能够被继承的,但是不允许访问。可显示变量名说明能继承,访问在提示的时候是会有红色线标记说明无法访问)

②★★★OC中的继承是 单继承 的,也就是说一个类只能有一个父类,不能继承多个父类

③★继承的合理性,不能乱继承,人不能继承狗,狗也不能继承人。(合乎逻辑性)



一段代码:



#import <Foundation/Foundation.h>



@interface Animal : NSObject

-(void)eat;

@end



@implementation Animal

-(void)eat

{

    NSLog(@"animal eat!");

}

@end



@interface Dog : Animal

-(void)eat;//这句话可以不写,我们可以直接写方法的实现部分(这里的eat:方法是重写之后的eat:方法,是继承父类的eat:方法,不属于私有方法,所以不写声明也可以)

//在Dog的父类Animal中有eat:方法,但是在Dog类中又重新定义了一下,这就叫做方法的重写。

@end



@implementation Dog

-(void)eat

{

    NSLog(@"dog eat!");

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Animal *ani=[Animal new];

        

        [ani eat];//ani对象调用的是Animal类中的eat:方法

        

        Dog *dog=[Dog new];

        

        [dog eat];//dog对象调用的是Dog类中的eat:方法(这里的eat:方法,是自己类中重写的)

//        在类的实例对象调用方法的时候,先查看自己本类中有没有该方法,如果该类中有,就先调用自己的,如果没有就去其父类中寻找,如果父类中再没有,那么再往上一层去寻找,找到后就执行,但是如果到NSObject中还没有的话就报错了。这里可以看成是就近原则。

    }

    return 0;

}





———————————————————————————————————————————

继承的一些注意事项



①子类不能定义和父类同名的变量,但是可以继承父类的变量。

如:我在Animal类中定义_age变量,然后Dog类继承Animal类,那么Dog类中是不能再定义一个_age变量的



②OC类支持单一继承,不支持多继承



③OC类支持多层继承



     动物类:Animal ——> 狗类:Dog ——> 军犬类:JunQuan





———————————————————————————————————————————

实例变量修饰符



访问修饰符:

@public:任意程序集

@protected:该类和其派生类(子类)  (如果声明时未做说明,那默认为是protected类型)

@private:该类     (@private类型的变量只能被继承但是不能访问,也就是说在子类中访问private类型的变量的时候,你只能看见提示有这个变量,但是上面有一道红线,表示无法被访问)

@package:框架级别的,作用域介于私有和公开之间,处于同一个框架之内就可以直接通过变量名访问





———————————————————————————————————————————

OC中的私有变量



在类的实现中(也就是.m文件中),也是可以声明成员变量的,但是在.m文件中声明的成员变量是@private(“纯/绝对”私有变量,既不能被继承,也不能被访问),而且在.m文件中声明的成员变量不能和.h文件中的成员变量同名,在这期间,即使是使用了@public等关键字修饰也是徒劳的。(也就是只能是@private类型的!!!)



总结一下上面的一段话:

①在.m文件中声明成员变量不能和.h文件中的成员变量同名。

②在.m文件中声明的成员变量只能是@private类型的。





一段代码:



#import <Foundation/Foundation.h>



@interface Animal : NSObject

-(void)run;

@end



//无论在.m文件中的哪个位置定义一个新的变量,都是绝对私有变量,无法被其他类继承和访问

int b=20;

@implementation Animal

int a=10;

-(void)run

{

    int c=30;

    NSLog(@"a=%d,b=%d,c=%d",a,b,c);

}

@end



@interface Dog : Animal



@end



@implementation Dog

-(void)run

{

//   NSLog(@"a=%d,b=%d",a,b);  //这样用是会报错的,因为a,b没有被继承过来

//   NSLog(@"c=%d",c);  //显然c也没有被继承过来

}



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Animal *ani=[Animal new];

        [ani run];

    }

    return 0;

}





建议大家一定要把代码拷贝到自己的Xcode中运行一下,即使很简单,也看看怎么得出的。





———————————————————————————————————————————

OC中的私有方法



在.h文件中没有声明,但是在.m文件中实现的方法,叫做私有方法。私有方法无法被子类继承和访问。





一段代码:



#import <Foundation/Foundation.h>



@interface Person : NSObject

-(void)eat;

@end



@implementation Person

-(void)eat

{

    NSLog(@"eat!");

    

    [self run];//①

    

    Person *p = [Person new];//②

    [p run];

}



-(void)run//既然这是一个私有方法,那我们应该如何去用他呢?经过在上面eat:方法中的测试,我们得到两种办法:

//①我们利用self在.m文件中的其他可访问的方法下访问

//②我们在.m文件中的其他可访问的方法下去实例化一个当前类的对象,然后用该对象调用这个私有方法(此时我们是在.m文件中实例化的这个对象,所以是可以访问run:方法的)

{

    NSLog(@"run!!!!!");

}

@end



@interface Student : Person



@end



@implementation Student



@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Student *st=[Student new];

        [st eat];

//        [st run];//run:方法是在Person类(Student的父类)的.m文件中实现的,并没有在.h文件中声明,所以run:方法是一个Person类的私有方法。所以无法被其子类Student继承和访问

        Person *p=[Person new];

        [p eat];

//        [p run];//这个地方也不能调用,就算是在main函数前加上 #import "Person.m" 也是不能用的。这是为什么呢?其实,有很多类,我们只提供给别人一部分可访问的东西,这些东西都在@interface @end中声明了,这就是一个接口,而我们不想让别人访问的,就不必声明。就像这个私有方法我们只是在.m文件中实现了而没有去声明一样。



    }

    return 0;

}





———————————————————————————————————————————

description方法——一个打印对象信息的方法





一段代码:



@interface Dog : NSObject

//@property (readonly, copy) NSString *description;  在NSObject类中我们打开之后发现里面有这么一句话,这个东西虽然暂时看是一个对象,但是里面解开之后底层是一个名为description的对象方法。用作输出对象的信息。我们还可以在.m文件中对这个方法进行重写。

{

    int _age;

    int _color;

}

-(void)setAge:(int)age;

-(int)age;



-(void)setColor:(int)color;

-(int)color;



-(void)run;





@end



@implementation Dog

-(void)setAge:(int)age

{

    _age=age;

}

-(int)age

{

    return _age;

}



-(void)setColor:(int)color

{

    _color=color;

}

-(int)color

{

    return _color;

}



-(void)run

{

    NSLog(@"run!");

}





//重写description方法

//这里我觉得可以看成是一个description的get方法,因为这个方法就是返回一个NSString类型的值

-(NSString *)description

{

    return [NSString stringWithFormat:@"_age:%d,_color:%d",_age,_color ];

//    这里是调用了NSString类的一个字符串格式化输出的类方法

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        //首先我们知道description是 描述 的意思,所以说这个方法是用来 打印对象信息 的。

        Dog *dog = [Dog new];

        [dog run];

        

        NSLog(@"%p",dog);//0x100206790   结果是一个字符串,我们知道,这里是打印对象dog的地址,用%p

        

        [dog setAge:12];

        [dog setColor:1];

        NSLog(@"%@",dog);//<Dog: 0x100206790>   这里用%@格式打印出来的是这样一个字符串,显然里面的一些数字表示的dog对象的地址,与上面我们打印的地址是一样的。这里其实是打印的dog对象的信息,而这里调用了一个description方法,这个方法是一个对象方法,其格式是这样子的。每当我们用%@的格式打印对象,都会出现这样的信息。但是我们在Dog类中并没有写description这个方法啊?答案就是这个方法存在于NSObject类中。

    }

    return 0;

}





———————————————————————————————————————————

版权声明:本文为博主原创文章,未经博主允许不得转载。

Objective-C 【继承、变量修饰符(私有变量/方法)、description方法】的更多相关文章

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

    四.OC基础--1.文档安装和方法重载, 1. 在线安装 xcode-> 系统偏好设置->DownLoads->Doucument->下载 2. 离线安装 百度xcode文档 ...

  2. OC继承以及实例变量修饰符

    这里基本上跟java一样 所以就简单写几点要注意的: 1)OC与java一样都只支持单继承可以多层继承(java单继承多实现) 2) OC中的实例变量修饰符前要加 @ 例如 @private 例如下面 ...

  3. java中的类修饰符、成员变量修饰符、方法修饰符。

    类修饰符: public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fin ...

  4. oc-19-成员变量修饰符

    /** 成员变量修饰符 1.@public:(公开)只要导入头文件,任何位置都可以直接访问. 2.@protected:(半公开)可以在本类和子类当中进行访问.(默认) 3.@private:(私有) ...

  5. 2、Java 基础语法标识符、修饰符、变量、 数组、枚举、关键字

    Java 基础语法 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如 ...

  6. GLSL ES 中的存储变量修饰符(const/attribute/uniform/varying/in/centroid in/out/centroid out)

    GLSL ES 3.00 中支持的存储变量修饰符 变量名称 作用 示例 const 编译过程常量,或者函数的只读参数 const vec3 zAxis = vec3 (0.0, 0.0, 1.0); ...

  7. java中的类修饰符、成员变量修饰符、方法修饰符

    类修饰符:  public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fi ...

  8. 转: 【Java并发编程】之五:volatile变量修饰符—意料之外的问题(含代码)

    转载请注明出处:     volatile用处说明     在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的.而随着JVM的成熟和优化,现在在多线程 ...

  9. 【Java并发编程】:volatile变量修饰符

    volatile用处说明     在JDK1.2之前,java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的.而随着JVM的成熟和优化,现在在多线程环境下volatile关键 ...

随机推荐

  1. Info.plist和pch文件的作用

  2. 【Away3D代码解读】(四):主要模块简介

    数据模块: Away3D中最核心的数据类是Mesh类,我们先看看Mesh类的继承关系: NamedAssetBase:为对象提供id和name属性,是Away3D大部分类的基类: Object3D:3 ...

  3. http协议分析工具

    资源推荐 1.Wireshark抓包软件 Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshar ...

  4. hbase运维

    NoSQL现在风生水起,hbase的使用也越来越广,但目前几乎所有的NoSQL产品在运维上都没法和DB相提并论,在这篇blog中来总结下我们在运维hbase时的一些问题以及解决的方法,也希望得到更多h ...

  5. 提高你的Java代码质量吧:少用静态导入

    一.分析  从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...

  6. HDU 5477 A Sweet Journey 水题

    A Sweet Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  7. android自动打包方法(ant+proguard+签名)

    前段时间做了一个android的网游项目,现在优化减少体积和防止别人反编译,需要把编译后.class进行混淆,开始在网上看了一些关于 ProGuard的介绍,基本上都是使用ADT自带的打包方式,那个打 ...

  8. [React Fundamentals] Using Refs to Access Components

    When you are using React components you need to be able to access specific references to individual ...

  9. iOS 10 升级后无法真机测试 Could not find Developer Disk Image

    ---2016年9月20日更新 iOS 升级到10之后,你会发现无法进行真机测试了.这种情况我在iOS 8.4 .9.3更新的时候也遇到过.原因是Xcode 的DeviceSupport里面缺少了iO ...

  10. iOS开发——新特性OC篇&IOS9 SDK新特性

    iOS9 SDK新特性 WWDC 2015苹果开发者大会是移动开发者一年一度的盛会,InfoQ中文站除了第一时间整理Keynote内容分享给大家之外,还邀请了资深的一线开发者分享他们的收获.本文为王巍 ...