#import <Foundation/Foundation.h>
#import "Student.h"
#import "Father.h"
#import "NotSon.h"
#import "Son.h"
#import "SonA.h"
#import "SonB.h"
#import "Animal.h"
#import "Cat.h"
#import "Dog.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
#pragma mark----------封装-------------------
/*
面向对象的三大特征:
封装,继承,多态
封装:隐藏内部的实现,稳定外部的接口
好处:
使用起来更加简单
变量更加安全
可以隐藏内部实现细节
开发速度更加快捷
作用:
方法封装了具体实现的代码
属性封装了实例变量
类封装了属性和方法
*/
NSString *name = @"Yong";
NSInteger age = 23;
NSString *homeAddress = @"GZ";
NSLog(@"Teacher name %@,%ld years old,living in %@",name,age,homeAddress);
Student *student = [[Student alloc] init];
//方法封装了具体实现的代码
[student helloWorld];
// [student hiGuys]; //私有方法不被外界所调用
}
#pragma mrak-----------------继承----------------
/*
继承:继承是避免冗余,提高代码的可重用和可维护性的有效手段
继承的传递性(书P54):直接父类,间接父类
继承需要符合的关系:is-a
子类和父类都需要满足 is-a 的关系,才存在继承关系.
继承概念下 is-a 关系是个单向的关系
子类具有父类的属性和行为,以及自身特色的属性和行为
要记住 X is-a Y 隐喻着X可以做出任何Y可以做出的事情,而且还有可能会做出更多的事情
*/
/*
继承的特点
1.使用继承可以实现代码的重用,减少代码冗余
2.OC中一个类可以继承另一个类,被继承的类称为 父类 或者 超类(基类),继承的类称为 子类 或者 派生类(孩子类)
3.子类可以直接"拥有"父类所有允许子类继承的属性和方法
4.子类可以改变父类中已有的方法,执行不同的代码实现
5.OC中只允许单一继承,因为多重继承会有称为"致命方块"的问题
*/
Father *father = [[Father alloc] init];
//点语法的本质是setter 和 getter
father.name = @"Yong";
[father sayHolle];
[father charge];
//如果这样写代码就会十分的冗余,并且这样写没有遵循面向对象的一个重要原则:write once,only once(写一次,仅写一次)
NotSon *notson = [[NotSon alloc] init];
notson.name = @"Chen";
[notson sayHolle];
[notson charge];
Son *son = [[Son alloc] init];
[son charge];
son.name = @"Yong";
son.homeAddress = @"GZ";
[son sayHolle];
[son race];
#pragma mark---------------NSObject中常用的方法及其功能----------------------
/*
NSObject中常用的方法及其功能
1.方法:+(id)alloc
功能:放回一个分配好内存的对象
说明:已经分配好内存的对象的实力变量会被初始化成默认值
2.方法:+(id)init
功能:对已经分配内存大的实例变量初始化(相当于便利初始化函数),不一定要默认的初始化函数,也可以自己写
说明:常见形式
-(id)init
{
if(self = [super init])
{
//初始化
}
return self;
}
3.方法:+(id)new
功能:同时调用了alloc和init
4.方法:-(Class)class
+(Class)class
功能:返回当前对象所属类
5.方法:-(Class)superclass
+(Class)superclass
功能:返回当前对象的父类
6.方法:-(BOOL)isKindOfClass:(Class)aClass
功能:判定receiver是否为Class的实例
说明:判断某个实例是否属于某个类或者子类
7.方法:-(BOOL)isMemberOfClass:(Class)aClass
功能:判断receiver是否为Class的实例
说明:只能判断某个实例是否属于某个类,不能判断是否属于某个父类
8.方法:+(BOOL)isSubclassOfClass:(Class)aClass
功能:判断是否为aClass的子类
说明:判断是否某个类的子类
9.方法:-(BOOL)respondsToSelector:(SEL)aSelector
功能:判断receiver是否响应某个消息,不包括类方法
10.方法:+(BOOL)InstancesRespondToSelector:(SEL)aSelector
功能:判断类的对象是否响应某消息
11.方法:-(BOOL)conformsToProtocol:(Protocol *)aProtocol
功能:判断是否实现某协议
12.方法:-(id)retain
功能:对象引用计数+1
13.方法:-(oneway void)release
功能:对象引用计数 -1
14.方法:-(id)autorelease
功能:对象引用计数 -1,且向autorelsesepool发送消息
15.方法:-(NSUInteger)retainCount
功能:返回当前引用计数
16.方法:-(void)perfromSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInvterval)delay;
功能:隔指定时间之后进行方法调用
*/
#pragma mark-------------------多态--------------------
/*
多态:多态就是对于不同的对象响应同一个方法时做出不同的反应,它是建立在继承的基础上面
1.继承同一父类的子类,他们本身具有自己的特性
2.继承同一父类的子类,在执行同一命令的时候,具有不同的效果
*/
SonA *sonA = [[SonA alloc] init];
sonA.name = @"SonA";
[sonA sayHolle];
SonB *sonB = [[SonB alloc] init];
sonB.name = @"SonB";
[sonB sayHolle];
/*
多态的好处:
1.可以简化编程接口
允许在多个类中定义同一消息接口
可以定义一个通用的调用方法,以简化调用
2.把不同的子类对象都当做父类来看
可以屏蔽不同子类对象之间的差异,写出同用的代码
做出通用的编程,以适应需求的不断变化
*/
//1.可以简化编程接口
id animal = nil; //由于id类型的通用性质(指向任意对象),我们可以将创建好的任意对象赋值给animal
animal = [Cat new];
[animal eat];
animal = [Dog new];
[animal eat];
//把不同的子类对象都当做父类来看
Animal *animalB = nil;
animalB = [Cat new];
[animalB eat];
animalB = [Dog new];
[animalB eat];
/*
开闭原则 和 里氏替换原则
开闭原则(Open Close Principle OCP)对扩展开放,对修改关闭
里氏替换原则(Liskvo Substitution Principle LSP)任何基类可以出现的地方,子类一定可以出现(基类就是已存在的用来派生新类的父类,也就是基类)
*/
Person *person = [[Person alloc] init];
Cat *cat = [Cat new];
Dog *dog = [Dog new];
[person feedCat:cat];
[person feedDog:dog];
[person feedAnimal:cat];
[person feedAnimal:dog];
//cat 和 dog 都是父类型Animal的指针,分别指向了子类型对象,然后当做参数传入了Person类中参数是Animal的-(void)feedAnimal:(Animal *)animal当中.这符合了里氏替换原则.
return 0;
}
在Person.h文件里
#import <Foundation/Foundation.h>
#import "Animal.h"
#import "Cat.h"
#import "Dog.h"
@interface Person : NSObject
-(void)feedCat:(Cat *)cat;
-(void)feedDog:(Dog *)dog;
//参数是父类型动物类型,无论喂养什么动物,都可以满足我们需求,不用修改Person类,增加我们响应的方法.符合了"开闭原则"
-(void)feedAnimal:(Animal *)animal;
@end
在Person.m文件里
@implementation Person
-(void)feedCat:(Cat *)cat
{
NSLog(@"人喂猫");
[cat eat];
}
-(void)feedDog:(Dog *)dog
{
NSLog(@"人喂狗");
[dog eat];
}
-(void)feedAnimal:(Animal *)animal
{
if ([animal isMemberOfClass:[Cat class]])
{
[animal eat];
NSLog(@"cat cat!!");
}
if ([animal isMemberOfClass:[Dog class]])
{
[animal eat];
NSLog(@"dog dog!!");
}
}
@end
在Dog.h文件里
@interface Dog : Animal
@end
在Dog.m文件里
-(void)eat
{
[super eat];
NSLog(@"Dog eats meat!");
}
@end
在Cat.h文件里
@interface Cat : Animal
@end
在Cat.m文件里
-(void)eat
{
[super eat];
NSLog(@"Cat eats fish!");
}
@end
在Animal.h文件里
@interface Animal : NSObject
-(void)eat;
@end
在Animal.m文件里
@implementation Animal
-(void)eat
{
NSLog(@"动物吃东西!");
}
@end
在SonB.h文件里
@interface SonB : Father
@end
在SonB.m文件里
@implementation SonB
-(void)sayHolle
{
[super sayHolle];
NSLog(@"I am SonB");
}
@end
在SonA.h文件里
@interface SonA : Father
@end
在SonA.m文件里
@implementation SonA
-(void)sayHolle
{
[super sayHolle];
NSLog(@"I am SonA");
}
@end
在Son.h文件里
//@inteface 类名:父类名,在OC中,使用冒号表示一个类继承了另一个类.冒号的含义是扩展,意味着子类出了继承父类的属性的方法外,还可以扩展出自己的特色属性和方法(一般情况下,我们继承于NSObject类,可以获取NSObject类中的大量有用的特性)
@interface Son : Father
@property(nonatomic,strong)NSString *homeAddress;
//自己的方法
-(void)race;
@end
在Son.m文件里
@implementation Son
//重新父类的charge方法
-(void)charge
{
/*
重新继承中的方法
特点:
1.发生在父类和子类之间
2.方法名相同,参数列表相同,返回类型相同
*/
NSLog(@"拿老爸的卡出了刷一下,