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

继承



一段代码:



#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. [iOS基础控件 - 3.5] NSBundle, UIImageView和UIButton的区别, 模拟器和文档

    1.NSBundle1> 一个NSBundle代表一个文件夹,利用NSBundle能访问对应的文件夹2> 利用mainBundle就可以访问软件资源包中的任何资源3> 模拟器应用程序 ...

  2. iOS开发核心语言Objective C —— 所有知识点总结

    C和OC对比 OC中主要开发在什么平台上的应用程序?答:可以使用OC开发Mac OS X平台和iOS平台的应用程序 OC中新增关键字大部分是以什么开头?答:OC中新增关键字大部分是以@开头 OC中新增 ...

  3. 第一次见4.3K电阻

    今天焊RC522的实验板,接收电阻买的是5.1K,焊接时发现丝层写的是432,阻为4.26K.理论值应该是4.3K

  4. [BZOJ]2132: 圈地计划 最小割

    圈地计划 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一 ...

  5. ajax请求,请求头是provisional are shown。请求未发送出去

    问题: ajax请求,请求没成功.ajax请求没有发送出去. 查看network,看到请求头处:Provisional headers are shown. 原因: 搜索了一下,网上说了几个原因. 1 ...

  6. hbase运维

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

  7. EF中Database.SqlQuery

    本文转载:http://www.cnblogs.com/daimage/archive/2012/07/04/2575844.html EF中Database.SqlQuery<TElement ...

  8. web工作方式,浏览网页,打开浏览器,输入网址按下回车键,然后会显示出内容,这个过程是怎样的呢?

    以下内容摘自<Go Web编程>,介绍的通俗易懂. 我们平时浏览网页的时候,会打开浏览器,输入网址后按下回车键,然后就会显示出你想要浏览的内容.在这个看似简单的用户行为背后,到底隐藏了些什 ...

  9. dialog统一标准调用方法(内部记录)

    更新base-config.js 对话框统一为三种形式(如后期需要再添加其他方式) //对话框--确定取消 //dialogOkFun:确定函数 dialogCancelFun:取消函数 functi ...

  10. windows平台下php版本问题–VC6/VC9和TS/NTS

    php下载页面中提供了4个下载版本,是vc6/vc9 与 TS/NTS的组合 VC6:legacy Visual Studio 6 compiler,就是使用这个编译器编译的.        VC9: ...