#import <Foundation/Foundation.h>
//#import "oc.h"
/*
@"" 表示将一个C的字符串转化为oc中的字符串对象NSString
NSString *string = @"haha";//OC中定义字符串
NSArray *arr = @{var1,var2,var3};
*/
//
//
//int main(int argc, const char * argv[]) {
// NSLog(@"this is a test");
// 字符串
// NSString *str=@"itcast";
// NSLog(@"%@",str);
// int a=10;
// int b=20;
// NSLog(@"a=%i,b=%i",a,b);
// test_oc();
// 数组
// NSArray *arr = @[@"aa",@"bb",@"cc"];
// for(NSString *str in arr){
// NSLog(@"%@",str);
// }
// NSArray *arr1=@[@"sadsadsa",@"sadsazas",@"zcdcewc",@"zddwd"];
// for(NSString *str in arr1){
// NSLog(@"%@",str);
// }
// 逻辑类型
// //Boolean类型的变量
// Boolean flag = true;//true代表1,false代表0
// //Bool也是用作逻辑判断
// BOOL flag = YES;//YES代表1,NO代表0
// if(flag){
// NSLog(@"好久没用了吧,臭小子。。");
// }
// @try @catch @finally <这个版块有问题>
// int a = 10;
// int b = 0;
// int result = 0;
// @try{
// result = a / b;
// NSException *ne=[NSException exceptionWithName:@"被整除为0的异常," reason:@"被整除为0了" userInfo:nil];
// @throw ne;
// }
// @catch(NSException *ne){
// NSLog(@"%@\n%@",ne.name,ne.reason);
//
// }@finally{
// NSLog(@"熟悉吧,哈哈。。。");
// }
//面向对象:是一种程序设计规范,可以大幅度提高软件项目的成功率,减少维护费,提高可移植性和可靠性。
//面向对象的三个特征:继承、封装、多态。
/*
面向对象与面向过程的区别:
面向过程
强调的是功能行为
关注的是解决问题需要哪些步骤
面向对象
将功能封装进对象,强调具备了功能的对象。
关注的是解决问题需要哪些对象。
面向对象是基于面向过程的。
*/
// return 0;
//}
//void test_oc(){
// printf("我是OC的函数");
// NSLog(@"我是NSLog\n");
//}
//@interface IPhone : NSObject
//
//{
// NSString *_color;
// int _size ;
// NSString *_cpu;
//}
//
//- (void) setColor:(NSString*)color;
//
//- (NSString*) color;
//
//- (void) setSize:(int)size;
//
//- (int) size;
//
//- (void) setCpu:(NSString*)cpu;
//
//- (NSString*) cpu;
//
//- (void) aboutMyPhone;
//
//- (void) call:(int) telNumber;
//
//- (void) sendMessage:(int) telNumber;
//
//
//@end
//
//
//@implementation IPhone
//
//- (void) setColor:(NSString *)color{
// _color = color;
//}
//
//- (NSString*)color{
// return _color;
//}
//
//- (void) setSize:(int)size{
// _size = size;
//}
//
//- (int) size{
// return _size;
//}
//
//- (void) setCpu:(NSString *)cpu{
// _cpu = cpu;
//}
//
//- (NSString*)cpu{
// return _cpu;
//}
//
//- (void) aboutMyPhone{
// NSLog(@"颜色:%@,大小:%d,cpu:%@",[self color] , [self size] , [self cpu]);
//}
//
//- (void) call:(int) telNumber{
// NSLog(@"正在接通%d,请耐心等待。。。",telNumber);
//}
//
//- (void) sendMessage:(int)telNumber{
// NSLog(@"发送给%d的信息正在发送中...",telNumber);
//}
//
//@end
//
//
//int main(){
// IPhone *phone = [IPhone new];
// [phone setColor:@"白色"];
// [phone setSize:13];
// [phone setCpu:@"122Hz,32G内存"];
// [phone aboutMyPhone];
// [phone call:10086];
// [phone sendMessage:10086];
// return 0;
//}
//#pragma mark -
//#pragma mark 人类
//@interface Person : NSObject
//
//{
// NSString *_name;
//
// int _age;
//
// float _weight;
//
//}
//#pragma mark -
//#pragma mark 方法:设置一些基本的属性
//- (void) setName:(NSString*)name andAge:(int) age andWeight:(float) weight;
//#pragma mark 方法:吃
//- (void) eats;
//#pragma mark 方法:散步
//- (void) walk;
//#pragma mark 方法:介绍自己
//- (void) introduce;
//
//@end
//
//@implementation Person
//
//- (void) setName:(NSString*)name andAge:(int) age andWeight:(float) weight{
//
// _name = name;
//
// _age = age;
//
// _weight = weight;
//}
//
//- (void) eats{
// self->_weight += 0.2;
//}
//
//- (void) walk{
// self->_weight -= 0.2;
//}
//
//- (void) introduce{
//
// NSLog(@"大家好!我叫%@,我的体重为:%f" , self->_name , self->_weight);
//}
//
//@end
//
//int main(){
//
// Person *person = [Person new];
//
// [person setName:@"小胖" andAge:13 andWeight:111];
//
// [person eats];
//
// [person eats];
//
// [person walk];
//
// [person introduce];
// return 0;
//}
/*
类方法与对象方法的区别:
对象方法:一般都以"-"号开头,类方法都以"+"开头。
对象方法只能由对象来调用,类方法只能由类调用。
函数与对象方法的区别:
1、对象方法的实现只能在@implemention ...@end中,声明只能在@interface...@end中。
2、函数的可以写在任何位置,包括@implemention ...@end中,但是写在@interface ..@end中会无法识别。函数的声明可以在main函数内部也可以在main函数外部。
3、对象方法不能当做函数一样调用。
4、对象方法归类和对象所有。
5、函数调用不依赖于对象。
6、函数内部不能直接通过成员变量名访问对象的成员变量。
*/
/*
字符串(NSString)
创建方式
1、创建常量字符串
NSString *string = @"itcast";
2、创建空字符串,赋值。
NSString *string = [NSString new];
string =@"dsajkd";
3、创建格式化字符串
NSString *string = [[NSString alloc] initWithString:[NSString stringWoyjFormat:@""]];
*/
//int main(){
// //创建一个字符空串
// NSString *string = [NSString new];
// string = @"welcome to guangzhou!";
// NSLog(@"%@",string);
// int i = 1;
// float j = 2.2f;
// //创建格式化字符串
// NSString *string1 = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%02d.This is %f string!",i,j]];
// NSLog(@"%@",string1);
// return 0;
//}
/*
字符串的操作
1、计算长度
[string length];//不包括后面的'\0',中文也只占一位。
*/
//int main(){
// NSString *string = @"wahaha德玛西亚";
// int size=[string length];
// NSLog(@"%d",size);
// return 0;
//}
/*
对象作为参数和返回值
*/
//#pragma mark Person类
//@interface Person : NSObject
//
//{
// @public
//
// NSString *_name;
//
// NSString *_sex;
//
// int _age;
//}
//
//@end
//
//@implementation Person
//
//@end
//
//#pragma mark Display类
//@interface Display : NSObject
//
//- (void) displayPerson:(Person*)person;
//
//- (Person*)changePerson:(Person*)person;
//
//@end
//
//@implementation Display
//
//- (void) displayPerson:(Person *)person{
// NSLog(@"姓名:%@,性别:%@,年龄:%d" , person->_name , person->_sex , person->_age);
//}
//
//- (Person*)changePerson:(Person *)person{
//
// person->_name = @"卡卡";
//
// person->_sex = @"妹子";
//
// person->_age = 18;
// return person;
//}
//
//@end
//
//int main(){
// Person *person = [Person new];
// person->_name = @"黄花闺女";
// person->_age = 79;
// person->_sex = @"男";
// Display *display = [Display new];
// [display displayPerson : person];
// [display changePerson : person];
// [display displayPerson : person];
// return 0;
//}
/*
类方法(类方法中不能使用类的成员变量)
1、类方法可以与对象方法同名(因为实例方法由对象访问调用,而类方法由类访问调用。)
2、类方法可以从父类继承而来,子类可以重写类方法。
3、在类方法里面使用self,这个self执行的类对象是class object,不是实例对象instance object
类方法的作用:
1、节省内存空间。
2、提高效率。
3、作为工具方法。
类方法注意:
1、可以调用对象方法和类方法(通过将对象作为参数传入方法)。
2、类方法不可以调用自身,否则会造成死循环。
对象方法
1、可以使用成员变量。
2、用对象调用对象方法。
3、对象方法可以调用当前对象或者其他对象的方法(通过将对象作为参数传入方法)。
*/
/*
匿名对象:没有名称的对象
优点:可以简化代码,方便方法调用。
缺点:匿名对象实例化后,只能正确的使用一次。
创建对象的方式:
类名 *对象名称 = [[类名 alloc] init];
类名 *对象名称 = [类名 new];
两种创建方式的区别:
1、alloc和init分别把分配内存和初始化的工作分开。它在分配内存的时候使用了zone,它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用的时候消耗很少的代价,提升程序的处理速度。
2、new每次都初始化为0,new把分配内存和初始化的工作一起完成了,先分配内存,然后调用类的构造函数。
*/
//#pragma mark 车类
//@interface Car : NSObject
//
//{
// @public
// int _color;
//}
//
//- (void) run;
//
//- (void) stop;
//
//@end
//
//@implementation Car
//
//- (void) run{
//
// NSLog(@"Car Start!,color:%d",_color);
//
//}
//
//- (void) stop{
//
// NSLog(@"Car Stop!");
//
//}
//@end
//
//#pragma mark 人类
//@interface Person : NSObject
//
//{
// NSString *_name;
//
// int _age;
//}
//
//- (void) goHome:(Car*)car;
//
//@end
//
//@implementation Person
//
//- (void) goHome:(Car *)car{
//
// [car run];
//}
//
//@end
//
//int main(){
// //匿名对象调用方法的使用
// [Car new]->_color = 1;
// [[Car new] run];
// //匿名类作为函数的实参使用
// Person *person = [Person new];
// [person goHome:[Car new]];
// NSLog(@"%@",person);//调用description方法(返回类型和对象的地址)
// return 0;
//}
/*
面向对象特征
封装(将数据隐藏起来,只能由此类的方法函数才可以调用)
原理:
实例变量只能被当前类的对象方法访问(默认也是这样的)。
实质就是把属性封装起来,不让外部调用。只能在自己的方法类调用。(提高get|set方法)
设计模式:
组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。
组合模式是类与类之间的关系,一个类中包含另一个类的对象就是组合模式。
组合模式是开发中最为常见的模式。
*/
/*
self和super关键字
super发送消息可以将方法实现分发给父类,可以重写一个已有的方法来修改或将它添加到现有的方法中,主要是在继承的子类重写了父类的方法但有想掉用父类中的方法可以使用super进行调用。
self关键字的使用(在什么方法中,就代表什么。)
1、在类方法中使用self
self在类方法中使用其指代的是当前类。
2、在对象中使用self
self在对象中使用其指代的是调用当前方法的对象。
*/
/*
继承
派生类方法属性 = 基类方法属性 + 派生类自己新增的方法和属性
注意点:1、基类的私有属性可以被继承,只是没有访问权限。
2、OC中的继承是单继承。
3、继承的合理性。
4、子类不能定义和父类同名的变量,但是可以继承父类的变量。
*/
/*
方法的重写
从父类继承的方法。可能不适合子类,可以在子类中重写父类的方法。重写后,父类的对象调用父类的方法。子类的对象调用子类的方法。从父类继承的方法,不适合子类的时候,可以直接声明父类的同名方法,并进行定义。不需要考虑父类中方法是否存在。
*/
//#import "oc.h"
//@interface Dog: Animal
//{
//
//}
//- (void)eat;
//@end
//int main(){
//
// return 0;
//}
/*
成员变量的访问修饰符
成员变量的访问修饰符@package(框架级别):作用域介于私有和公开之间,只要处于同一个框架中就可以直接通过变量名访问。
成员变量的访问修饰符使用注意点:
1、在类的实现即.m文件中也可以声明成员变量,但是只能声明@private的成员变量。
并且在.m文件中定义的成员变量不能与它的头文件.h文件中的成员变量同名。
2、在@interface @end之间声明的成员变量如果不做特别的说明,那么默认为@protected。
3、一个类继承了另一个类,那么这个类就拥有了父类的所有成员变量和方法。(不过有些它不能直接访问)
*/
/*
description方法(返回对象的描述信息(返回类名和对象的内存地址))
格式:NSLog(@"%@",对象名称); L467
注意点:
1、不要再description方法中同时使用%@和self。同时使用@和self,代表调用self的description方法。会导致死循环。
*/
/*
多态(某一类事物的多种状态)
(不同对象以自己的方式响应相同名称的方法的能力称为多态)
产生多态的前提条件:
1、有继承关系,有方法重写。
2、(在函数中的主要实现方式)父类的声明变量指向子类对象。父类 *父类变量 = [子类 new];
优点:
1、简化编程接口,它允许在类与类之间重用一些习惯性的命名,不用为每一个新加的函数命名一个新的名字。
2、提高代码的扩展性和复用性。
原理:
动态类型:能使程序直到执行的时候才能确定对象的所属的类型。
id类型:通用指针类型,它是弱类型,编译的时候不进行类型检查。
<!>动态绑定:
1、动态类型绑定能使程序直到执行的时候才确定要对对象调用的实际方法。
2、OC中可以在运行的时候加入新的数据类型和新的程序模块,动态类型识别,动态绑定,动态加载。(个人感觉与spring中的切面编程差不多)
*/
/*
<!>
类的本质(就是一个对象(类对象))
类对象
生命周期:从程序编译的时候开始直到程序运行结束。
它使一种数据结构,存储类的基本类型。
类对象保存的信息在程序编译的时候确定,在程序启动的时候加载在内存中。
<!>如果消息的接受者是类名,则类名代表类对象
运行的时候,所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,没有实例的isa都指向该实例的类对象。
从类对象里面可以知道类的信息、可以响应的方法。
作用:
1、调用类方法。
2、实例化变量。
*/
//@interface Dog : NSObject
//
//{
// int age;
//
// int LegNum;
//
//}
//+ (void) run;
//- (void) run;
//@end
//
//@implementation Dog
//
//+ (void) run{
// NSLog(@"我是类方法,我开始跑了");
//}
//- (void) run{
// NSLog(@"我是对象方法,我开始跑了");
//}
//
//@end
//int main(){
// //获取类对象的方式
// //1、
// Class c = [Dog class];
// //2、
// Dog *dog = [Dog new];
// Class c1 = [dog class];
// [c1 run];//注意类对象只能调用类方法,不要越界啊。
// NSLog(@"%p",c);//当调用description方法的时候,类对象仅返回类名,没有地址。
// NSLog(@"%p",c1);
// Dog *d1 = [c1 new];
// [d1 run];
// return 0;
//}
/*
<!>
类对象的存储
SEL(全称Selector): 表示方法的存储位置。
格式:
SEL sel = @selector(方法名);
[对象 performSelector:sel];
SEL中寻找方法的过程:
1、首先把方法名包装成sel类型的数据。
2、根据SEL数据找到对应的地址。
3、根据方法地址调用相应的方法。
注意点:在这个寻找操作的过程中是缓存的,第一次找的时候是一个一个找,性能消耗比较大。但是之后再用到就可以直接使用了。(与java中的框架差不多)
总的来说:SEL其实就是对方法的一种封装,将方法包装成一个SEL类型的数据,然后去寻找对应的方法地址。找到地址后就可以调用方法。
*/
/*
OC中的点语法
本质:转换成相应的set和get方法,如果没有get和set方法,则不能使用点语法。(与java中不同,java中指的是的访问成员变量,而这里指的是调用成员变量的get|set方法)
*/
/*
@property
它使编译器的指令。(编译器指令:告诉编译器要作什么。)
@property告诉编译器声明属性的访问器(getter|setter)方法。(说白了就是以后只要标注该关键字,就不需要在声明set和get方法了)
@synthesize
在m文件中定义set|get方法的实现。
@property与@synthesize是成对出现的。但是它只能写在m文件中,至于为什么吗,自己想。(主要往作用域方面想)
*/
//@interface Person : NSObject
//{
// //在这里我就算不写成员变量,它也会给我加进来一个(int _age;),这就是@property的魅力。(但是注意:该变量是私有的)
//}
//@property int age; //只要加上@property之后,属性就不需要再写声明了。爽吧。。。
//
//@end
//
//@implementation Person
//
//@synthesize age;//只要加上@synthesize之后,属性就补需要再写实现了。
- (void) setAge:(int)age{
_age = age;
}
- (int)age{
return _age;
}
//
//@end
//int main(){
// Person *person = [[Person alloc] init];
// person.age = 10;//使用点语法
// NSLog(@"%d",person.age);
// return 0;
//
//}
/*
多态:运行不同的类定义相同的方法。
动态类型(程序直到执行时才能确定所属的类)
感觉就是多态,程序直到执行的时候才确定是哪一种类型,调用哪一中类型里面的方法。
静态类型(特定的形态)
在使用静态类型的时候,编译器尽可能的确保变量的用法在程序中始终保持一致。
使用静态类型的优点:提高程序的可读性。
动态绑定
实质:在oc中一个对象内是否调用指定的方法不再由编译器决定,而是由运行的时候决定。
在OC中,对象不调用方法,而是接收消息。
接收消息的格式为[receiver message]
运行过程:运行时系统首先确定接收者的类型,然后根据消息名在类的方法列表中选择相应的方法执行。
在源代码中消息也称为选择器(selector)
<!<不清楚内部的内存结构图>>
消息函数的执行过程:
1、通过第一个参数的receiver找到它的isa指针,然后在isa指向的Class对象中使用第二个参数selector查找方法。
2、如果没有找到,就使用当前Class对象中的新的isa指针到上一级的父类的Class对象中查找。
3、当找到方法后,再依据receiver中的self指针找到当前的对象,调用当前对象的具体实现的方法。然后传递参数,调用实现方法。
*/