//
//  Animal.h

#import <Foundation/Foundation.h>

@interface Animal : NSObject
{
    int _age;
}

- (void)eat;  //.h是变量和方法的声明, .m文件是对方法的实现。
@end
//
//  Animal.m
#import "Animal.h"

@implementation Animal
- (void)eat
{
    NSLog(@"吃东西");
}
@end
//
//  Cat.h

#import <Foundation/Foundation.h>
#import "Animal.h"

@interface Cat : Animal

@end
//
//  Cat.m

#import "Cat.h"

@implementation Cat

- (void)eat
{
    NSLog(@"吃鱼");
}
@end
//
//  Dog.h

#import <Foundation/Foundation.h>
#import "Animal.h"

@interface Dog : Animal

- (void)kanJia;   //继承,.m文件是自己方法的实现和父类继承过来的方法的实现
@end
//
//  Dog.m

#import "Dog.h"

@implementation Dog


- (void)eat
{
    NSLog(@"啃骨头");
}

- (void)kanJia
{
    NSLog(@"看家, 旺旺叫");
}
@end
//
//  Person.h

#import <Foundation/Foundation.h>
#import "Dog.h"
#import "Cat.h"

@interface Person : NSObject

/*
+ (void)food:(Dog *)dog;

+ (void)foodCat:(Cat *)cat;

// 骆驼
// 狗熊
// 豹子
// 大象
// 猴子
// 鸡
// 猪
// 草泥马
// ...
 */

+ (void)food:(Animal *)a;
@end
//
//  Person.m

#import "Person.h"

@implementation Person
+ (void)food:(Animal *)a
{
    [a eat];
}
@end
//
//  main.m
//  多态
#import <Foundation/Foundation.h>
#import "Dog.h"
#import "Cat.h"
#import "Animal.h"
#import "Person.h"
#import "Pig.h"

int main(int argc, const char * argv[]) {

    Dog *d11 = [Dog new];
    [d11 eat];//啃骨头
    
    Cat *c1 = [Cat new];
    [c1 eat];//吃鱼
    
    // 多态: 事物的多种表现形态
    // 动态类型: 在编译的时候编译器只会检查当前类型对应的类中有没有需要调用的方法,所以不会报错,在运行时,系统会自动判断a1的真实类型
    Animal *a1 = [Dog new];
    [a1 eat];//啃骨头
    
    // 注意点: 在多态中, 如果想调用子类特有的方法必须强制类型转换为子类才能调用,[a1 kanJia];
    Dog *d1 = (Dog *)a1;
    [d1 kanJia];//看家, 旺旺叫
    [(Dog *)a1 kanJia];//看家, 旺旺叫
    
    Dog *d = [Dog new];
    Cat *c = [Cat new];
    Pig *p = [Pig new];
    
    [Person food:d];//啃骨头
    [Person food:c];//吃鱼
    [Person food:p];//大口吃
    /*
     在程序中如何表现:
     父类指针指向子类对象
    */
    return 0;
}