张超超OC基础回顾04_实例变量修饰(@public),点语法,self关键字,多态,继承
零、实例变量修饰符
/*
@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关键字,多态,继承的更多相关文章
- 张超超OC基础回顾02_成员变量(属性),局部变量,全局变量的区别
成员变量: 写在类声明的大括号中的变量, 我们称之为 成员变量(属性, 实例变量) 成员变量只能通过对象来访问 注意: 成员变量不能离开类, 离开类之后就不是成员变量 成员变量不能在定义的同时进行初始 ...
- 张超超OC基础回顾03_结构体类型作为成员变量的特殊用法
直接上例子: 要求: 合理的设计一个”学生“类 学生有* 姓名* 生日两个属性和说出自己姓名生日方法 要求利用设计的学生类创建学生对象,并说出自己的姓名和年龄 描述学生类 事物名称: 学生(Stud ...
- 张超超OC基础回顾01_类的创建,申明属性,以及本质
一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...
- 张超超OC基础回顾_05 property修饰符,id类型,instancetype。。。
一.property 如果给一个属性同时提供了getter/setter方法, 那么我们称这个属性为可读可写属性 如果只提供了getter方法, 那么我们称这个属性为只读属性 如果只提供了setter ...
- 四.OC基础--1.文档安装和方法重载,2.self和super&static,3.继承和派生,4.实例变量修饰符 ,5.私有变量&私有方法,6.description方法
四.OC基础--1.文档安装和方法重载, 1. 在线安装 xcode-> 系统偏好设置->DownLoads->Doucument->下载 2. 离线安装 百度xcode文档 ...
- OC继承以及实例变量修饰符
这里基本上跟java一样 所以就简单写几点要注意的: 1)OC与java一样都只支持单继承可以多层继承(java单继承多实现) 2) OC中的实例变量修饰符前要加 @ 例如 @private 例如下面 ...
- Python基础-类变量和实例变量
Python基础-类变量和实例变量 写在前面 如非特别说明,下文均基于Python3 大纲: 1. 类变量和实例变量 在Python Tutorial中对于类变量和实例变量是这样描述的: Genera ...
- oc 中四种实例变量的范围类型@private@protected@public@package
To enforce the ability of an object to hide its data, the compiler limits the scope of instance vari ...
- 直接访问实例变量 VS 通过点语法访问实例变量
直接访问实例变量,不会经过 OC 的方法派发机制,速度比较块.会直接访问对象的实例变量对应的内存. 直接访问实例变量,不会调用"设置方法".绕过了相关属性对应的"内存管理 ...
随机推荐
- 怎么把openrety 里边的 table 优雅的打印出来
1.安装 loarocks 库以后 2.安装 Penlight 插件 3.如下图所示 4.利用dump 函数优雅的打印 table
- 【前端】HTML入门笔记
教程 HTML 指的是超文本标记语言 (Hyper Text Markup Language).使用标记标签来描述网页 HTML 提示:使用小写标签\属性\属性参考手册\HTML颜色\HTML颜色名 ...
- 51nod 1089 最长回文子串 V2(Manacher算法)
回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. 收起 输入 输入Str(Str的长度 <= 100000) ...
- Asp.net页面间传值方式汇总
七种传值方式,分别是:URL传值,Session传值,Cookie传值,Server.Transfer传值,Application传值,利用某些控件的PostBackUrl属性和使用@Previous ...
- 【sqlite】判断sqlite数据库表是否存在
SQLite语句: cmd.CommandText = "SELECT count(*) from sqlite_master where type='table' and name='ta ...
- 【BZOJ2908】又是nand 树链剖分+线段树
[BZOJ2908]又是nand escription 首先知道A nand B=not(A and B) (运算操作限制了数位位数为K)比如2 nand 3,K=3,则2 nand 3=not (2 ...
- ASP.NET 2.0缓存
MSDN上缓存概述: http://msdn2.microsoft.com/zh-cn/library/726btaeh(VS.80).aspx 一.页输出缓存 1.设置 ASP.NET 页缓存的两种 ...
- bzoj 1415 [Noi2005]聪聪和可可——其实无环的图上概率
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1415 乍一看和“游走”一样.于是高斯消元.n^2状态,复杂度n^6…… 看看TJ,发现因为聪 ...
- oscache源码浅析
oscache作为本地缓存框架,存储模型依然是通用的缓存键值对模型.oscache使用HashTable存放数据,我们看下源码: GeneralCacheAdministrator: /** * Ge ...
- UniDac 使用日记(转)
UniDAC使用日记 1. UniQuery默认状态为行提交,使用前根据需要设置readonly或cachedupdates属性 2. UniQuery.Filter默认大 ...