objective-c--- 类、继承、多态、点语法、@class

1、面向对象的三大特性

  1. 封装性
  2. 继承性
  3. 多态性

2、类方法和对象方法

  • 类方法: 以+开头 调用类方法: [类名 类方法]
  • 对象方法:以-开头 调用对象方法:[对象名 对象方法]
  • 类方法和对象方法可以同名:
    比如: - (void) test;
    +(void)test;是正确的

3、关键字self

self其实是个指针,谁调用了方法,seLf就指向谁
例子:

背景:一个类中有一个成员变量:_age

- (void)test{
    int _age = 20;
    NSLog(@"%d",_age);
}
//若要指向成员变量 _age,用self->_age

4、继承

继承使用注意:

  • 不允许子类和父类拥有相同名称的成员变量
  • 父类必须什么在子类的前面

重写

  • 子类重新实现父类中的某个方法,覆盖父类以前的做法

组合关系

当Score类中的属性:int _cScore ; int _ocScore;
和Student类中的属性:int _cScore ; int _ocScore

虽然有部分相同的成员变量,但是不采用继承,因为在现实生活中,学生类继承分数类,不符合逻辑关系

符合逻辑的继承举例:Student类继承Person类 @interface Student: Person

若不符合逻辑的继承应该考虑到组合关系:在Student类中:Score *_score;

5、Super的作用

  • 直接调用父类中的某个方法
  • super处在对象方法中,那么就会调用父类的对象方法,super处在类方法中,那么就会调用父类的类方法

6、super的使用场合

  • 子类重写父类的方法时想保留父类的一些行为
[super eat]//调用父类中eat这个方法

7、多态

  • 父类指针指向子类对象
    背景:Animal类是Dog的父类
Animal *a = [Dog new];

用一段代码来体验多态的好处

Animal类:

@implementation Animal
- (void)eat{
    NSLog(@"动物吃东西");
}
@end

Cat类:在.h文件中已经继承了Animal类

@implementation Cat
- (void)eat{
    NSLog(@"猫吃东西");
}
@end

Dog类:在.h文件中已经继承类Animal类

@implementation Dog
- (void)eat{
    NSLog(@"狗吃东西");
}
@end

main文件中:

#import "Animal.h"
#import "Dog.h"
#import "Cat.h"
#import 
//喂食的函数
void feed(Animal *a)
{
    [a eat];
}
int main(int argc, const char * argv[]) {

    Dog *dog = [[Dog alloc] init];
    Cat *cat = [[Cat alloc] init];
    Animal *animal = [[Animal alloc] init];
    feed(dog);
    feed(cat);
    feed(animal);

    NSLog(@"---------------");
    Animal *dog2 = [Dog new];
    Animal *cat2 = [Cat new];
    Animal *animal2 = [Animal new];
    [dog2 eat];
    [cat2 eat];
    [animal2 eat];

}

输出结果:
2015-03-16 20:11:49.436 objective-c知识点[3651:39141] 狗吃东西
2015-03-16 20:11:49.437 objective-c知识点[3651:39141] 猫吃东西
2015-03-16 20:11:49.437 objective-c知识点[3651:39141] 动物吃东西
2015-03-16 20:11:49.437 objective-c知识点[3651:39141] —————
2015-03-16 20:11:49.437 objective-c知识点[3651:39141] 狗吃东西
2015-03-16 20:11:49.437 objective-c知识点[3651:39141] 猫吃东西
2015-03-16 20:11:49.438 objective-c知识点[3651:39141] 动物吃东西

多态的局限性

  • 父类类型的变量不能调用子类的方法

解决方法:强制转换类型

8、NSString

  • objective-c 字符串 @”chenfanfang” 也是一个对象,是一个NSString对象
  • objective-c 字符串的创建不像常规对象的创建方法
    常规对象的创建方法:Person *p = [Person new];
    字符串的创建:
    方法1:NSString *str = @"itcast;"
    方法2:NSString *str = [NSString stringWithFormat:@"my age is %d",23];
    方法3:NSString *str = [NSString stringWithString:@"chenfanfang"];

获取字符串的长度

int length = [str length];
//对应的点语法为 str.length
int length1 = str.length;

9、pragma mark 用来标记,注释

//会生成分割线的注释
#pragma mark - 注释
//不声成分割线的注释
#pragma mark   注释

10、点语法

注意:

  • 点语法不是直接访问成员变量,不像java,oc访问成员变量唯一方法: 对象名->成员变量

点语法的本质:

  • 其实点语法的本质还是调用方法
  • 当使用点语法时,编译器会自动展开成相应的方法。
    例如:
stu.age = 10;//编译器会自动展开成如下的方法
[stu setAge:10];

int age = stu.age;//展开为
int age = [stu age];

点语法的死循环注意

在set方法和get方法别用点语法,否则会产生死循环。以下两个方法会产生死循环

- (void)setAge:(int)age{
    self.age = age;
    //展开成:[self setAge:age];
}

- (int)age{
    return self.age;
    //展开成:return [self age];
}

@class

@class的使用场景

对于循环依赖关系来说,比方,A类引用B类,同时B类引用A类

A类中

#import "B.h"

@interface A:NSObject
{
   B *b;
}
@end
B类中

#import "A.h"

@interface B:NSObject
{
   A *a;
}
@end

以上这种代码编译会报错,当使用@class在两个类相互申明,就不会出现编译错误

@class使用概括

使用@class 类名;就可以引用一个类,说明一下它是一个类

@class和#import的区别

  • #import方式会包含被引用类的所有信息,包括被引用类的变量和方法。@class方式只是告诉编译器在A.h文件中 B *b 只是类的申明,具体类里有什么信息,这不需要知道,等实现文件中真正用到时,才会真正去查看B类中信息。
  • 如果上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了。
  • 在.m实现文件中,若果需要引用到被引用类的实体变量或者方法时,还需要使用#import方法引入被引用类。

你可能感兴趣的:(objective-c)