零、实例变量修饰符

/*
@public 就是实例变量修饰符 @public
>可以在其它类中访问被public修饰的成员变量
>也可以在本类中访问被public修饰的成员变量
>可以在子类中访问父类中被public修饰的成员变量 @private
>不可以在其它类中访问被private修饰的成员变量
>可以在本类中访问被private修饰的成员变量
>不可以在子类中访问父类中被private修饰的成员变量 @protected
>不可以在其它类中访问被protected修饰的成员变量
>可以在本类中访问被protected修饰的成员变量
>可以在子类中访问父类中被protected修饰的成员变量 注意: 默认情况下所有的实例变量都是protected @package
>介于public和private之间的
如果是在其它包中访问那么就是private的
如果是在当前代码所在的包种访问就是public的 实例变量修饰符作用域: 从出现的位置开始, 一直到下一个修饰符出现
如果没有遇到下一个实例变量修饰符, 那么就会修饰后面所有的实例变量
*/
@interface Person : NSObject
{
@public
int _age; @private
double _height; @protected
double _weight; @package
NSString *_name;
NSString *_tel;
NSString *_email;
}
@end

一、setter&getter

其实setter和getter就是对成员变量的封装,由于开发中一般不会给成员变量直接变为@public,不会让成员变量直接暴露给自己这个类之外的其他类别,但是又得提供了接口让其他类来访问,所以就又了setter和getter方法,我们可以在setter和getter中过滤自己不想的值,防止别人更改自己的类(如果是自己的类是可以直接给自己的类的成员变量赋值的,默认就是私有的)。

@interface Gun : NSObject
{
/*
由于将来我们经常需要定义一些方法来操作成员变量,而每个方法都必须有一个有意义的名称,而想名字非常难,所以就有了getter-setter方法
getter-setter方法格式和写法都是固定的,所以只要有getter-setter方法我们就不用煞费心思的去想方法名称了,解决我们起名字难问题
并且getter-setter方法还是程序员之间的一种规范,以后别人只要想给属性赋值立刻就会想到getter-setter方法,这样降低了程序员之间的沟通成本 */
int _size; //尺寸
} /*
setter方法:
作用: 设置成员变量的值
格式:
1. setter方法一定是对象方法
2. 一定没有返回值
3. 一定以set开头, 并且set后面跟上需要设置的成员变量的名称去掉下划线, 并且首字母大写
4. 一定有参数, 参数类型一定和需要设置的成员变量的类型一致, 并且参数名称就是成员变量的名称去掉下划线
*/
- (void)setSize:(int)size; /*
getter方法:
作用: 获取成员变量的值
格式:
1. getter方法一定是对象方法
2.一定有返回值, 而且返回值一定和获取的成员变量的类型一致
3.方法名称就是获取的成员变量的名称去掉下划线
4. 一定没有参数
*/
- (int)size; @implementation Gun // setter
- (void)setSize:(int)size;
{ //成员变量以下划线开头的好处,就是可以区分局部变量和成员变量,可以过滤,如果该size是自己不想要的,则不用赋值给成员变量_size _size = size;
} // getter
- (int)size
{
return _size;
}

二、点语法

如果给属性提供了getter和setter方法, 那么访问属性就又多了一种访问方式 , 点语法

点语法其实它的本质是调用了我们的setter和getter方法

点语法是一个编译器的特性, 会在程序翻译成二进制的时候将.语法自动转换为setter和getter方法

如果点语法在=号的左边, 那么编译器会自动转换为setter方法

如果点语法在=号的右边, 或者没有等号, 那么编译器就会自动转换为getter方法

   p.name = @"lnj";

   // 和下面这个是相等的
 [p setName:@"lnj"]; p.age = ; // 这个是setter p.height = 1.75; // 下面的点语法为gettet
NSLog(@"age = %i, name = %@, height = %f", p.age, p.name, p.height)

三、继承

场景:

当前代码存在的问题,重复代码太多,可以利用继承来解决当前重复代码太多的问题,只要A类继承了B类, 那么A类就拥有了B类的所有属性和方法(对象方法和类方法)。

比如有一个手机类(Phone):

@interface Phone : NSObject
{
int _cpu;
} // 打电话
- (void)signalWithNumber:(NSString *)number; // 发短信
- (void)sendMessageWithNumber:(NSString *)number andContent:(NSString *)content; // 品牌
+ (void)brand;
@end @implementation Phone - (void)signalWithNumber:(NSString *)number
{
NSLog(@"利用手机打电话给%@", number);
} - (void)sendMessageWithNumber:(NSString *)number andContent:(NSString *)content
{
NSLog(@"利用手机发短信给%@, 内容是%@", number, content);
} + (void)brand
{
NSLog(@"品牌");
}
@end 

一个iPhone类和Andriod继承自Phone,iPhone和Andriod就有了Phone中的所有属性和方法(类方法和对象方法),如果想扩展父类中方法可以使用super来实现父类方法,然后再补充自己的。

@interface Iphone : Phone
// 继承父类相当于将父类的属性copy了一份到子类中
/* 继承父类之后不能重写父类的属性,重复定义了
{
int _cpu;
} // 打电话
- (void)signalWithNumber:(NSString *)number; // 发短信
- (void)sendMessageWithNumber:(NSString *)number andContent:(NSString *)content;
*/ - (void)setCpu:(int)cpu;
- (int)cpu;
@end @implementation Iphone
/*
- (void)signalWithNumber:(NSString *)number
{
NSLog(@"利用iPhone手机打电话给%@", number);
} - (void)sendMessageWithNumber:(NSString *)number andContent:(NSString *)content
{
NSLog(@"利用iPhone手机发短信给%@, 内容是%@", number, content);
}
*/ - (void)setCpu:(int)cpu
{
_cpu = cpu;
} - (int)cpu
{
return _cpu;
} @end

四、多态

多态是建立在继承的基础上的,只有先有了继承才有多态。

父类指针指向子类对象。

优点:提高了代码的扩展性

注意点:如果父类指针指向子类对象, 如果需要调用子类特有的方法(既该方法只有子类有,父类是没有的), 必须先强制类型转换为子类才能调用。

#import "Dog.h" // 子类
#import "Cat.h" // 子类
#import "Animal.h" // 父类
#import "Person.h"
#import "Pig.h" // 子类 int main(int argc, const char * argv[]) { /*
Dog *d = [Dog new];
[d eat]; Cat *c = [Cat new];
[c eat];
*/
/*
// 多态: 事物的多种表现形态
// 动态类型: 在编译的时候编译器只会检查当前类型对应的类中有没有需要调用的方法
// 在运行时,系统会自动判断a1的真实类型(编译和运行时候不一样)
Animal *a1 = [Dog new];
[a1 eat]; // 注意点: 在多态中, 如果想调用子类特有的方法必须强制类型转换为子类才能调用
// [a1 kanJia];
Dog *d1 = (Dog *)a1;
[d1 kanJia];
*/ Dog *d = [Dog new];
Cat *c = [Cat new];
Pig *p = [Pig new];

  // 比如person中有一个方法给动物喂食物,直接传递给一个继承自Animal类型的对象(dog,cat,pig)就行,运行时候会自动甄别是属于哪个对象的,这样就简单许多了。不然在person中得创建多个给不同动物喂东西的方法,采用多态,用一个方法就搞定了。
[Person food:d];
[Person food:c];
[Person food:p]; return ;
}

五、self

self不能离开类,离开了类就没有了任何意义

self在类中:

@implementation Iphone

/*
注意点:
类方法中可以直接调用类方法
类方法中不可以直接调用对象方法
类方法中不能访问成员变量,因为成员变量只能用对象来调用,类中的self代表着类
*/
+ (void)carameWithFlahlightStatus:(FlahlightStatus)status
{
if (status == kFlahlightStatusOpen) {
// [Iphone openFlahlight];
// 其实在类方法中调用类方法除了可以使用类名调用以外, 还可以使用self来调用
[self openFlahlight];
}else
{
// [Iphone closeFlahlight];
// self == Iphone
[self closeFlahlight];
}
NSLog(@"拍照");
} + (void)openFlahlight
{
NSLog(@"打开闪光灯");
} + (void)closeFlahlight
{
NSLog(@"关闭闪光灯");
} @end

self在对象中:

/*
注意:
如果self在对象方法中, 那么self就代表调用当前对象方法的那个对象
如果self在类方法中, 那么self就代表调用当前类方法的那个类
总结:
我们只用关注self在哪一个方法中 , 如果在类方法那么就代表当前类, 如果在对象方法那么就代表"当前调用该方法的对象"
*/
- (void)carameWithFlahlightStatus:(FlahlightStatus)status
{
if (status == kFlahlightStatusOpen) {
// 其实self不仅仅可以调用我们的类方法, 还可以调用对象方法
// self == 对象 == p
NSLog(@"self = %p", self);
[self openFlahlight];
}else
{
[self closeFlahlight];
}
NSLog(@"拍照");
} - (void)openFlahlight
{
NSLog(@"打开闪光灯");
} - (void)closeFlahlight
{
NSLog(@"关闭闪光灯");
}

补充点self的注意点:

/*
注意:
>self会自动区分类方法和对象方法, 如果在类方法中使用self调用对象方法, 那么会直接报错
>不能在对象方法或者类方法中利用self调用当前self所在的方法 使用场景:
可以用于在对象方法之间进行相互调用
可以用于在类方法之间进行相互调用 可以用于区分成员变量和局部变量同名的情况
*/
+ (void)carameWithFlahlightStatus:(FlahlightStatus)status
{
if (status == kFlahlightStatusOpen) {
// NSLog(@"self = %p", self);
[self openFlahlight]; // p
}else
{
[self closeFlahlight];
}
NSLog(@"拍照");
} + (void)openFlahlight
{
NSLog(@"打开闪光灯");
// NSLog(@"self = %p", self);
// 死循环
[self openFlahlight]; // p
} + (void)closeFlahlight
{
NSLog(@"关闭闪光灯");
} - (void)setCpu:(int)cpu
{
// 区分局部变量和成员变量
self->cpu = cpu;
}

张超超OC基础回顾04_实例变量修饰(@public),点语法,self关键字,多态,继承的更多相关文章

  1. 张超超OC基础回顾02_成员变量(属性),局部变量,全局变量的区别

    成员变量: 写在类声明的大括号中的变量, 我们称之为 成员变量(属性, 实例变量) 成员变量只能通过对象来访问 注意: 成员变量不能离开类, 离开类之后就不是成员变量 成员变量不能在定义的同时进行初始 ...

  2. 张超超OC基础回顾03_结构体类型作为成员变量的特殊用法

    直接上例子: 要求: 合理的设计一个”学生“类 学生有* 姓名* 生日两个属性和说出自己姓名生日方法  要求利用设计的学生类创建学生对象,并说出自己的姓名和年龄 描述学生类 事物名称: 学生(Stud ...

  3. 张超超OC基础回顾01_类的创建,申明属性,以及本质

    一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...

  4. 张超超OC基础回顾_05 property修饰符,id类型,instancetype。。。

    一.property 如果给一个属性同时提供了getter/setter方法, 那么我们称这个属性为可读可写属性 如果只提供了getter方法, 那么我们称这个属性为只读属性 如果只提供了setter ...

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

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

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

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

  7. Python基础-类变量和实例变量

    Python基础-类变量和实例变量 写在前面 如非特别说明,下文均基于Python3 大纲: 1. 类变量和实例变量 在Python Tutorial中对于类变量和实例变量是这样描述的: Genera ...

  8. oc 中四种实例变量的范围类型@private@protected@public@package

    To enforce the ability of an object to hide its data, the compiler limits the scope of instance vari ...

  9. 直接访问实例变量 VS 通过点语法访问实例变量

    直接访问实例变量,不会经过 OC 的方法派发机制,速度比较块.会直接访问对象的实例变量对应的内存. 直接访问实例变量,不会调用"设置方法".绕过了相关属性对应的"内存管理 ...

随机推荐

  1. 设计模式之访问者(visitor)模式

    在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根据药品名称和数量计算总价,而药房工作人员根据药品名称和数量准备药品,如下图所示. 在软件开发中,有时候也需 ...

  2. vue前端开发那些事——前言

    如上图所示,用vue开发一个小型网站所涉及到的知识点.这只是前端部分已经这么多了.接下来我分解开来说. 1.Node 当我们开发vue项目的时候,首先要安装Node.js,那么我们即使当时不理解为什么 ...

  3. linux离线搭建Python环境及安装numpy、pandas

    1.安装python2.7.3 Cent OS 6.5默认装的有python2.6.6,需要重新安装python2.7.3下载地址:https://www.python.org/downloads/s ...

  4. 20165222 实验一java开发环境的熟悉

    实验内容及步骤 实验一 Java开发环境的熟悉-1 1 建立“自己学号exp1”的目录 2 在“自己学号exp1”目录下建立src,bin等目录 3 javac,java的执行在“自己学号exp1”目 ...

  5. rpm 软件包离线安装

    1. 插件安装(可选) yum install yum-plugin-downloadonly 2. 只下载不安装(perl 演示) yum install --downloadonly --down ...

  6. C++笔记之CopyFile和MoveFile的使用

    1.函数定义 CopyFile(A, B, FALSE);表示将文件A拷贝到B,如果B已经存在则覆盖(第三参数为TRUE时表示不覆盖) MoveFile(A, B);表示将文件A移动到B 2.函数原型 ...

  7. log4j及其log4j2的使用

    简单的说 log4j2 是log4j2的升级版,据说采用了一些新技术(无锁异步.等等),使得日志的吞吐量.性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活.其使用方式 ...

  8. IPv6与IPv4最主要的不同

    IP第6个版本(IPv6),是互联网协议的新版本,设计为IP第4版本(IPv4,RFC-791)的继任.从IPv4升级到IPv6主要的改变有以下几类: 扩展地址容量 IPv6将IP地址的位址从32位提 ...

  9. 关于urlDecode和tomcat一些源码

    1. 看下面源码,找到%号,每次加2,然后将16进制转换为int,也就是%号后两位加2得到16进制,转换为int ) < numChars) && (c=='%')) { ,i+ ...

  10. python学习(七) 更加抽象

    python是面向对象的语言. 7.1 对象的魔力 7.1.1 多态 不管是字符串还是列表,count()函数都可以正常工作. >>> ['ab','b','c'].count('c ...