Skip to content

Latest commit

 

History

History
190 lines (132 loc) · 5.8 KB

2.类(二).md

File metadata and controls

190 lines (132 loc) · 5.8 KB

类(二)

OC中类的声明和Java、Go完全不一样。类的声明竟然用@interface... 我还记得原来看到iOS同事写的代码的时候,一看,卧草,这是啥,满屏幕的符号....

OC中类的声明和实现分为两部分:

  • .h文件:类的声明文件,用于声明成员变量、方法。类的声明使用关键字@interface和@end。.h文件只是一个声明,并不对方法进行实现,也就是说,只是声明一个方法名,方法的返回值类型(我是理解成了Java中的接口,毕竟是面向接口编程嘛....)。

  • .m文件:类的实现文件,用于实现.h中声明的方法,类的实现使用关键字@implementation和@end。方法的声明和实现都必须以+或者-开头。+表示类方法(静态方法),当方法中不设计类的成员变量时,可以把方法声明称类方法。这样做的好处是可以不用声明类的示例对象,减少内存空间的占用,提高运行效率,只能由类(名)调用,可以理解成java中的static方法。-表示对象方法(动态方法),只能通过创建对象来调用。 。成员变量的作用域有三个:@public表示全局,@protected表示只能在类的内部和子类访问。@private表示只能在类的内部访问。

例如Test.h:

#import <Foundation/Foundation.h>

@interface NSObject (Test)

@end

Test.m

#import "Test.h"

@implementation NSObject (Test)

@end

下面用一个Person类的例子说明一下:

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject {
    // 为类定义属性的时候,属性名词必须以_开头。虽然不加也不会报错,但是必须要加
    @public
    NSString *_name;
    int _age;
}
// 两个参数,一个name,一个age,注意写法 前面-表示实例方法
- (void)set:(NSString *) name : (int) age;
// 前面+表示类方法,可以理解成java的static
+ (void)print;
@end

Person.m

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

@implementation Person

- (void)set:(NSString *)name : (int) age {
    _name = name;
    _age = age;
}

+ (void)print {
    NSLog(@"name: %@, age : %d", _name, _age);
}

@end

main.m

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

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [Person new];
        // 调用方法
        [person set : @"hello" : 20];
        // 调用属性,下面的两种方式都可以
        person->_age = 30;
        (*person)._name = @"world";
        // 类方法不用创建对象,可以直接通过类名访问
        [Person print];
    }
    return 0;
}

执行结果:

2018-09-29 11:41:10.314817+0800 Hello[2569:38493] name: world, age : 30
Program ended with exit code: 0

总结一下上面的知识点:

  • @interface Person : NSObject NSObject是父类,相当于Java中的Object, Person : NSObject是说Person类继承了NSObject,继承都是通过这种形式来嘚

    例如,我们可以自定义一个@interface Student : Person

  • 类的创建
    用[],后面加上new,关键是返回的对象要带*

    Person *person = [Person new];
    

    注意这里是person,因为这个是指针,在person里面畜类执行Person类的属性外,还有一个isa的指针,这个指针指向对应的类所指向的在代码段中的空间。

  • 方法声明:

    • (返回值类型)方法名称;
    • (返回值类型)方法名称:(参数类型)形参名称;
    • (返回值类型)方法名称:(参数类型)形参名称1 : (参数类型)参数名称2 : (参数类型)参数名称3; 如果方法有多个参数,建议用下面的写法,可以提高代码的阅读性:
    • (返回值类型)方法名称:(参数类型)参数名称 and:(参数类型)参数名称2 and:(参数类型)参数名称3;

    方法头中的数据类型都要用小括号括起来。

  • 方法调用
    用[]和空格分割,而且参数要用:传递

    output = [object method];  
    output = [object method : input];  
    

方法与函数的区别

  • C中学习的函数,叫函数
void test() {

}
  • OC类中写的方法,叫方法
- (void)sayHi;

都是用来封装一段代码,表示一个相对独立的功能。 函数或方法只要被调用,封装在里面的代码就会被执行。

不同点:

  • 语法不同。

  • 定义的位置不一样。 OC方法的声明只能卸载@interface的大括号外面,实现只能写到@implementation之中。 函数除了在函数的内部和@interface的大括号之中外,其他的地方都可以写。

    就算把函数卸载勒种,这个函数仍然不属于类,所以创建的对象中也没有这个函数。注意:函数不要写到类中,虽然这样也是可以的,但是是极度不规范的。

  • 调用的方式不一样。 函数可以直接调用,但是方法必须先创建对象,通过对象来调用。

  • 方法是属于类的。而函数是独立的,不属于任何。

写完这个类,我已经崩溃了....满屏的大括号、冒号,一个函数两个参数竟然还要用and连接一下,而且调用方法不用()也不用.尽然用大括号加空格隔开......

But...终究还是要继续学的...

对象作为方法的参数或返回值

#import "Dog.h"
- (void)test:(Dog *)dog;

参数类型是类指针。

(Dog *)是说这个参数的类型是Dog的指针。

- (Dog *)test1;