张超超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 的方法派发机制,速度比较块.会直接访问对象的实例变量对应的内存. 直接访问实例变量,不会调用"设置方法".绕过了相关属性对应的"内存管理 ...
随机推荐
- POJ 2954 Triangle (pick 定理)
题目大意:给出三个点的坐标,问在这三个点坐标里面的整数坐标点有多少个(不包含边上的) 匹克定理:I = (A-E) / 2 + 1; A: 表示多边形面积 I : 表示多边形内部的点的个数 E: 表示 ...
- Java基础总结大全
一.基础知识: 1.JVM.JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性. java语言是跨平台,jvm不是跨平台的. J ...
- Weex入门篇——Mac 安装Weex
相关文档:http://blog.csdn.net/jasonblog/article/details/51863173 前言 相比较于React Native的“Learn once, write ...
- C# 自定义exe引用的dll路径
MSDN原文:https://msdn.microsoft.com/library/twy1dw1e(v=vs.100).aspx <runtime> 的 <assemblyBind ...
- CODEVS1049 棋盘染色
题目大意:01矩阵,1表示黑色,0表示白色,求将白色染成黑色最少的次数 使黑色成为一整个联通块. 题解: 搜索bfs 90... dfs判断连通 #include<iostream> #i ...
- (转)xshell基本操作步骤
xshell 操作方法如下: mkdir +文件夹名 (新建目录) ls 文件浏览(使用ls命令列出文件列表的信息,默认情况下为当前目录下的所有文件,并按照字母顺序排列) file [选项].. ...
- SQL语言分为五大类
SQL语言分为五大类:DDL(数据定义语言) - Create.Alter.Drop 这些语句自动提交,无需用Commit提交.DQL(数据查询语言) - Select 查询语句不存在提交问题.DML ...
- Java 数组的浅拷贝和深拷贝
浅拷贝: 在堆内存中不会分配新的空间,而是增加一个引用变量和之前的引用指向相同的堆空间. int[] a = {1,2,3,4,5}; int[]b = a; public class Test { ...
- (转)winform下UPD通信的简单应用
本文转载自:http://blog.csdn.net/wanlong360599336/article/details/7557046 先看效果图: 使用UDP的好处就是不需要三次握手,但是缺点就是存 ...
- VS2012编译Lua5.3.1
编译静态库: 1.新建Win32控制台应用程序Lua5.3,下一步,应用程序类型选择:DLL,空项目,完成. 2.项目名右键属性,配置属性--项目默认值--配置类型:静态库(.lib) 3.头文件上右 ...