黑马程序员-OC语言基础学习(二)

本文深入探讨了Objective-C中的面向对象编程概念,包括封装、继承、多态等核心特性,并通过示例代码详细解释了这些特性的应用及注意事项。

---------------------- IOS培训.期待与您交流! ----------------------

OC学习笔记二
---既然决定14年要好好的努力一次,那么就不要再轻言放弃,不再在随波逐流。只有努力过、拼搏过,才会知道自己行还是不行!为自己加油!---
---总结的知识点可能有不正确的地方,如果有发现请留言给我,我一定及时更正,不让错误的知识去误导大家,有好的意见也可大声提出来,小弟一定愿意采纳---

面向对象的三大特性

1、封装
通过内部的方法去改变变量的值
set方法 (提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应的过滤)
命名规范:
方法名必须以set开头,set后面跟上成员变量的名称,成员变量的首字母必须大写。
返回值一定是void,一定要接收一个参数,而且参数类型跟成员变量类型一致
形参的名称不能跟成员变量一样

@interface Student
{ 
// @public 成员变量尽量不要用
int age;
}

- (void) setAge:(int) newAge;  //set方法
- (void) age;  //get方法
@end
@implementation Student
- (void) setAge:(int) newAge
{
age = newAge;
}
- (void) age
{
return age;
}
@end


int main()
{
Student *s = [Student new];
[s setAge:10];  //通过方法去访问成员变量  实现对成员变量的封装隐藏
[s age];
}


get方法 返回对象内部的成员变量
命名归范:
肯定有返回值,返回值类型肯定与成员变量类型一致
方法名跟成员变量名一样,(与JAVA的不同)不需要接收任何参数

封装的好处:
隐藏程序的内部细节,防止程序被恶意的修改,保证成员的正确性。

2、成员变量的命名规范
一定以下划线开头 _
让成员变量和get方法的名称分开;可以跟局部变量区分开,一看到下划线开头的变量,一般都是成员变量

3、练习(通过不同参数满足程序)
下面的程序在比较方法是一个是通过传递数值,一个是通过指针。
注意get set方法的命名及成员变量的命名规范
#import <Foundation/Foundation.h>

@interface Score : NSObject
{
    int _c;
}

- (int) compareC:(int) c;    //传c的数值

- (int) compareC2:(Score *) c1;   //传指针

- (int) setC:(int) newC;
- (int) c;
@end

@implementation Score

- (int) compareC:(int) c  //传c的数值
{
    return _c - c;
}

- (int) compareC2:(Score *) c1
{
    return _c - c1->_c;
}

- (int) setC:(int) newC
{
    _c = newC;
}

- (int) c
{
    return _c;
}

@end

int main()
{
    Score *s = [Score new];
    [s setC:20];
    Score *s1 = [Score new];
    [s1 setC:30];
   
    int scoreC =  [s compareC:[s1 c]];
    int static2 = [s compareC2:s1];
    NSLog(@"通过直接传值%i", scoreC);
    NSLog(@"通过传递指针%i", scoreC);
    
}

4、OC的弱语法
OC在运行过程中才会检测对象有没有实现相应的方法。如果没有实现在编译时只会警告
一旦程序在运行时出现问题那么就会发生闪退的动作
5、类方法(可以提高效率)
类方法都是以 + 开头 对象方法以 - 开头
可以通过类名直接调用
@interface Student : NSObject
+ (void) test;
@end
@implementation Student
+ (void) test
{
NSLog(@"haha");
}
@end
int main()
{
[Student test]; 


Student *s = [Student new];
[s test];
}

类方法只能用类名调用,编译可以通过但是运行会报错
类方法和对象方法可以同名。
类方法是不能访问成员变量(实例变量)
对象方法能够访问当前对象的成员变量(实例变量)

优点:
不依赖对象,执行效率高;能用类方法尽量用类方法
使用场合: 当方法内部不需要使用到成员变量时,就可以用类方法。

工具类(基本没有任何成员变量,里面的方法基本都是类方法)


@interface Tool : NSObject
{
+ (int) sumOfNum1: (int)num1 andNum2:(int) num2;
}
@end
@implementation Tool
+ (int) sumOfNum1: (int)num1 andNum2:(int) num2
{
return num1 + num2;
}
@end
int main()
{
[Tool sumOfNum1: 10 andNum2:20];
}


6、self关键字
self:指向当前的调用者,(调用方法的对象),代表着当前对象

@interface Student : NSObject
{
    int _age;
}
- (void) setAge:(int)age;
- (void) age;
- (void) test;
@end

@implementation Student

- (void) setAge:(int)age;
{
    _age = age;
    self->_age = age;   //等价的
}
- (void) age
{
    return _age;
    //return self->_age;   等价
}
- (void) test
{
    NSLog(@"haha", _age);  
    int _age = 30; 
    NSLog(@"haha", _age);  //输出30 找到最近的_age; 
    NSLog(@"haha", self->_age);  //输出20 self指向调用方法的对象
}

@end

int main()
{
    Student *s = [Student new];
    
    [s setAge:20];  
    [s test];   //输出haha10
}

self的用途
概念 指向了当前的对象
self出现在对象方法中,self就代表对象
self在类方法中,就代表类
在对象方法中可以利用self->成员变量名 访问当前对象内部的成员变量
[self 方法名];  访问对象的方法。

@interface Student : NSObject
- (void) run;
- (void) jump;
@end

@implementation Student

- (void) run
{
    NSLog(@"haha");
}
- (void) jump
{
[self run];
    NSLog(@"hehe");
}
@end

int main()
{
    Student *s = [Student new];
    
    [s jump];   //输出 哈哈 呵呵
}

self使用注意:  注意调用方法时发生死循环


7、继承
Class A 继承 Class B  
Class A  就有有B的所有东西包括属性和方法, 其中Class A  为子类,Class B为父类
@interface Animal   : NSObject
{
    int _age;
}
- (void) setAge:(int)age;
- (void) age;
@end

@implementation Animal    

- (void) setAge:(int)age;
{
    _age = newAge;
}
- (void) age
{
    return _age;
}
@end

@interface Dog : Animal    // : Animal 继承了Animal 相当于拥有了Animal里面的所有成员变量和方法
@end
@implementation
@end

int main()
{
    Dog *d = [Dog new];
    
    [d setAge:20];
}


继承的好处
 抽取重复的代码 ; 建立了类之间的关系 ;子类可以拥有父类中所有成员变量和方法
 NSProxy  NSObject  是OC中的两个基本类(root class)
注意 基本上所有类的根类是NSObject  
继承的坏处
耦合性太强

9、继承使用注意:
注意子类、父类定义的位置,子类不能定义到父类前面
不允许子类和父类拥有相同名称的成员变量,但是可以允许有相同名称的方法
调用方法时,优先找自己本身的方法,然后在去找父类
父类中的方法可以交给子类去实现,在父类中不去实现
重写:子类重新实现父类中的某个方法,覆盖父类以前的方法。
(每个类中都有一个superclass的指针,指向自己的父类,每个对象中都有一个isa的指针,指向所属的类)
10、继承和组合
当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中,
当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类
继承 A是B
组合 A拥有B
A
{
int _age;
}


B                     // B : A  继承的方式
{
A *_a; //组合的实现形式
int _weight;
}

11、super关键字
调用父类中的方法,可以调用类方法也可以调用对象方法,具体调类方法还是对象需要看具体的情况。
直接调用父类的某个方法
super处在对象方法中,那就调用对象方法
super处在类方法中,那就调用类方法
使用情况: 子类重写父类的方法时,想保留父类的一些行为


12、多态(多种形态)
@interface Animal : NSObject
- (void) age;
@end

@implementation Student
- (void) age
{
    return _age;
}
@end

@interface Dog : Animal    // : Animal 继承了Animal 相当于拥有了Animal里面的所有成员变量和方法
@end
@implementation
- (void) age
{
    return _age;
}
@end

int main()
{
//多种形态
    Dog *d = [Dog new];   Dog类型
    //多态:父类指针指向子类对象 
    Animal *d = [Dog new];   
    //调用方法时会检测对象的真实形象
    [d age];  //调用Dog类的age方法
    NSObject *d = [Dog new];  //也是多态
    return 0;
}


13、多态的好处
/
/ 如果参数中使用的是父类类型,可以传入父类,子类对象,降低设置子类作为参数的局限性
void feed(Animal *a)    //如果参数类型设置为Dog *a  那么当猫调用时就不科学,所以利用多态设置为父类类型
{
[a eat];
}
int main()
{
Dog *d = [Dog new];
Cat *c = [Cat new];
feed(d);
feed(c);
}

14、多态的局限性
没有继承就没有多态
代码体现 父类类型指针指向子类对象
父类类型的变量不能用来调用子类特有的方法,(可以运行,编译会警告,但是语法上不符合)
解决这种情况可以进行类型转换
(如 子类B中有方法 A,父类A中没有方法 method
如下定义  
A *a = [B new];  父类型的变量a
[a method];  这样调用是不允许的,编译时会有警告
解决上面的问题可以将父类型变量a 进行类型转化
B *b = (B *)a; 
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值