关于静态类型、动态类型、id、instancetype

简介: 在实际开发与学习中,特别常见的概念:静态类型、动态类型、id、instancetype。了解这些概念,存储在实际编码中非常有用。

静态类型

  • 一个指针变量定义为特定的对象时,使用的是静态类型,在编译的时候就知道这个指针变量所属的类,这个变量总是存储特定类的对象,默认情况下所有的数据类型都是静态数据类型

    @interface Person : NSObject
    property (nonatomic,strong) NSString *name;
    -(void)run;
    @end
    @implementation Person
    -(void)run{
        NSLog(@"run");
    }
    @end
    int main(int argc, const char * argv[]) {
        Person *p = [[Person alloc]init];
        p.name = @"ABC";
        [p run];
        return 0;
    }
  • 静态数据类型的特点:

    • 在编译的时候就知道变量的类型
    编译时就知道p是Person类型
    • 知道变量中有哪些属性和方法

      @property (nonatomic,strong) NSString *name;
      -(void)run;
    • 在编译的时候就可以访问这些属性和方法
     p.name = @"ABC";
      [p run];
    • 并且如果是通过静态数据类型定义变量,如果访问了不属于静态数据类型的属性和方法,那么编译器就会报错

    error.png

动态类型

  • 指程序直到执行时才确定对象所属的类

    @interface Person : NSObject
    @property (nonatomic,strong) NSString *name;
    -(void)run;
    @end
    @implementation Person
    -(void)run{
        NSLog(@"run");
    }
    -(void)test{
        NSLog(@"test");
    }
    @end
    
    @interface Student : Person
    @property (nonatomic,assign) int age;
    -(void)eat;
    @end
    @implementation Student
    -(void)eat{
        NSLog(@"eat");
    }
    @end
    
    int main(int argc, const char * argv[]) {
        id obj1 = [[Person alloc]init];
        [obj1 run];
        id obj2 = [[Student alloc]init];
        [obj2 eat];
        return 0;
    }
  • 动态数据类型的特点:

    • 在编译的时候编译器并不知道变量的真实类型,只有在运行的时候才知道它的真实类型

      id obj1 = [[Person alloc]init];
      id obj2 = [[Student alloc]init];

id类型与instancetype

  • id类型

    • id是一种通用的对象类型,它可以指向属于任何类的对象,可理解为万用指针,相当于C语言的void*数据类型,id也是一个动态数据类型,可以用来定义变量,作为函数参数,作为函数返回值等等

      • id == NSObject*(万能指针)
      • NSObject* 是一个静态类型
    • 由于动态数据类型可以调用任意方法,所以有可能调用到不属于自己的方法,而编译时又不报错,所以导致运行时错误
    • 使用场景:多态,可以减少代码量,避免调用子类特有的方法需要强制类型转化
    • id类型不能使用点语法,因为点语法是编译器的特性,而id类型是运行时的特性
    • 尽量使用静态类型,静态类型可以更早的发现错误,提高可读性
  • instancetype

    • instancetype在编译时就可以判断对象的真实类型
    • instancetype只能用于返回值
    • 自定义的构造方法,返回值尽量使用instancetype,不要用id
目录
相关文章
|
2天前
|
JavaScript 前端开发 Java
02 # 类型基础:强类型与弱类型
02 # 类型基础:强类型与弱类型
27 0
|
2天前
|
存储 测试技术 C++
03 # 类型基础:动态类型与静态类型
03 # 类型基础:动态类型与静态类型
25 0
|
2天前
|
C++ Rust NoSQL
Rust 数据类型 之 类C枚举 c-like enum
Rust 数据类型 之 类C枚举 c-like enum
34 0
Rust 数据类型 之 类C枚举 c-like enum
|
7月前
|
JavaScript
TypeScript 具有可选的静态类型和基于类的面向对象编程,具体应用案例解析
TypeScript 具有可选的静态类型和基于类的面向对象编程,具体应用案例解析
45 0
|
9月前
|
Java
Java 中String类型变量的使用
Java 中String类型变量的使用
50 0
|
存储 Java Go
GO语言-07派生类型:map和结构体(上)
自己学习Go语言学习过程中的记录与总结,希望对你能有帮助。 第七篇(上):学习Go语言的Map,以及使用type定义自己的类型,包括type+struct定义结构体
120 0
|
JavaScript 前端开发
学习TypeScrip1(基础类型)
void 类型的用法,主要是用在我们不希望调用者关心函数返回值的情况下,比如通常的异步回调函数
60 0
学习TypeScrip1(基础类型)
实战小技巧15:如何判断类为基础类型or基础类型的包装类
判断一个类是否为基础类型属于常规操作了,一般我们遇到这种case,要怎么处理呢? 一个一个的if/else判断? 还是其他的操作姿势?
872 0
go string类型的特性
获取ascii类型字符的长度个数和获取utf8类型字符长度的个数
86 0
|
存储 Rust
Rust编程语言中的定义类型
Rust编程语言中的定义类型
107 0