零、实例变量修饰符

/*
@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. Gif图片验证码类

    新开发的安全验证码类,支持生成Gif图片验证码(带噪点,干扰线,网格,随机色背景,随机自定义字体,倾斜,Gif动画). 上图: 字体及字体文件的路径需要在类中$FontFilePath及$FontFi ...

  2. I/O多路复用方案

    1. 本节思维导图 2. 基本的网络编程接口 2.1 基于TCP的通信模型 2.2 基于UDP的通信模型 3. 非阻塞的服务器程序 file.pipe.fifo.socket在默认创建过程中都是阻塞的 ...

  3. LeetCode Design TinyURL

    原题链接在这里:https://leetcode.com/problems/design-tinyurl/description/ 题目: How would you design a URL sho ...

  4. 通过docker构建zabbix监控系统

    下载zabbix的镜像 $ docker pull berngp/docker-zabbix Using default tag: latest latest: Pulling from berngp ...

  5. android中HttpClient的应用(POST方法)

    首先在http://hc.apache.org/downloads.cgi下载HttpClient包 直接看代码 import android.os.Handler; import android.o ...

  6. 容器中跨主机的网络方案-Weave

    容器中的网络是建立docker集群的重要内容. 本文将介绍如何用Weave实现容器的多节点互通. Weave是一个开源的项目,其网站为: https://www.weave.works/ 其工作原理相 ...

  7. MyBatis collection的两种形式——MyBatis学习笔记之九

    与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...

  8. Java-Runoob:Java 教程

    ylbtech-Java-Runoob:Java 教程 1.返回顶部 1. Java 教程 Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言. Java可运行于 ...

  9. ILMerge最佳实践

    背景 为了生成的代码更加简捷,复制方便,常常会把多个可执行文件合并成一个. 方案 Project=>Properties=>Build Events=>Edit Post-build ...

  10. Ansible之Playbooks的when语句

    在使用ansible做自动化运维的时候,大多数情况下都执行某些任务的时候都需要依赖某个变量的值或者是上一个任务的执行结果.如,根据facts信息中的系统版本相关的信息来确定使用哪种包管理器安装软件.A ...