ObjectiveC-08-OOP面向对象程序设计-类的分离与组合
本节用一简短的文章来说下是ObjectiveC中的类。类其实是OOP中的一个概念,概念上简单来讲类是它是一组关系密切属性的集合,所谓的关系就是对现实事物的抽象。
- 上面提到的关系包括很多种,比如has a, is a,has some等;
- 关系是一种抽象过程,源于对事务的理解,同时还要平衡开发的成本,这是一门艺术;
类的结构
OOP标准结构
下图是一张通用的类完整结构图表示,本章暂时只讲最基础的部分,后续章节会围绕这个基础逐渐深入展开。

几点需要说明下:
- 在OOP世界中,所有的类都有一个默认的父类,一般称为基类。比如java里的基类名为Object,ObjectiveC中的基类名称为NSObject。
- OOP中不允许多继承,ObjC也不例外;
- 协议可以实现多个,即一个类可以实现多种不同的协议;
OOP在ObjC中的实现
ObjectiveC中的代码实现模式:

几点需要说明下:
- 在ObjectiveC中,会把一个类拆分成两个文件接口(.h)和实现(.m)。
- ObjectiveC中的文件只是一个载体,具体的定义是由关键标识来定义的,比如在一个.h文件中可以定义多个接口定义;在一个.m文件中也可以定义多个接口的实现
在同一个.m文件中书写全部的代码,这种方式并不推荐,因为会给维护带来很大问题。
#import <Foundation/Foundation.h>
// ----------------------类声明----------------------------
@interface Fraction : NSObject
@end // Tire// -----------------------类实现---------------------------
@implementation Fraction- (NSString *) description
{return (@"I am a tire. I last a while");
} // description@end // Tire// -----------------------main入口函数---------------------------
int main(int argc, const char * argv[]) {@autoreleasepool {Fraction *engine = [Fraction new];}return 0;
}// main
所以推荐的类组织方式是:
分离接口和实现
把@interface和@implementation代码定义在同一个.m文件中,这种方式呢做练习用还可以,如果是正式的程序就不太方便了。因为这样的话在代码行数比较多时维护会是个大总是,所以最好的方法是分离接口和实现,实现分而治之,如下:

创建类文件
使用XCode工具,在“New File时”选择Cocoa class创建文件时会自动分离.h和.m,如下图所示:

在下一步窗口中添填写新创建的类名称,也可以选择需要继承的父类(父类可以是自定义的类):

最后设置文件存放目录,也可以设置目标和群组,复杂的项目可以有多个组和目标:

- Group:Group主要是用于管理项目的源文件,比如可以创建两个Group,一个用于存放UI文件,一个用于存放处理程序类。Group不是java中package的概念,它是XCode的一个逻辑分组并不会真正的移动文件位置,甚至可以让Group指向磁盘上某个特定的文件夹;
- Target:简单可理解应用编译后的运行环境,比如一个IOS程序,其可以设置多个不同的目标如iphone12、iphone13等,每个目标采用不同的配置,这样也比较方便测试其兼容性;
.h类声明实现
相当于类功能的描述,默认格式上文件名与类名相同。在.h文件中一般用于定义类的@interface指令、公共的struct定义、enum常量、#defines和extern全局变量。新创建一个Fraction.h文件,代码示例如下:
#import <Foundation/Foundation.h>@interface Fraction : NSObject-(void) print;@end //end Fraction
.m类功能实现
相当于类功能的实现,默认格式上文件名与类名相同。在.m一般用于定义类的@implementation指令、私有的struct定义、extern全局变量定义。新创建一个Fraction.m文件
如果创建的是以.mm为后缀的文件则可以同时使用C++和ObjectiveC语法,示例代码如下:
#import "Fraction.h"@implementation Fraction {//私有属性int numerator;int denominator;
}
- (void) print {NSLog(@"%i / %i", numerator, denominator);
}- (void) setNumerator:(int) n {numerator = n;
}- (void) setDenominator:(int) d {denominator = d;
}
@end
分离后的代码会有如下特点:
- 在@interface中引入的头文件,可直接继承到@implementation实现中不必重复导入,比如在.h文件中import <Foundation/Foundation.h>,则.m文件中就不需要再写一遍了(虽然可以);
- 在 @implementation 实现中也可以定义 @interface 中未出现过的方法和变量,但要注意不要和.h文件中定义的变量名重复;
- 在@implementation或@interface中定义的方法的参数名称尽量不要和自定义的变量重名,所以给变量前面加上self是一个非常好的习惯,比如下列代码;
//声明部分
-(void) setNumerator: (int) name;//实现部分
NSString *name;
- (void) setDenominator:(int) name {name = name;//上面这行代码必须替换为如下代码,否则会发生错误self.name = name;
}
类的实例化
类可以通过new或alloc关键字实现实例化,类的实例化是一大块内容,本节只需简单了解其使用调用,如果用XCode创建工程,则会默认生成一个名为main.m的文件,里面包含一个main方法(注意:一个工程只允许存在一个main()方法)。
// -----------------------main入口函数---------------------------
int main(int argc, const char * argv[]) {@autoreleasepool {Fraction *engine = [[Fraction alloc] init];}return 0;
}
类的组合
上述就是最简单类的实现,下面看到类封装的基本用法。也是一种最简单的设计模式组合。比如描述一辆汽车:

对象组合其实是一种设计思想,并不是一种技术框架实现。类的扩展有分类和协议两种技术,另一种技术就是合成对象,它可以定义一个类包含其他类的一个或多个对象,这个新类就是所谓的合成对象。即手动处理,比如父子类的实现可修改成如下代码:
@interface Car: NSObject{Tires *tires[4]; //4条轮胎Engine *engine; //1个引擎
}@interface Tires: NSObject{int par; //标准的气压值int position;//安装位置
}@interface Engine: NSObject{NSString *name; //引擎名称
}
相关文章:
ObjectiveC-08-OOP面向对象程序设计-类的分离与组合
本节用一简短的文章来说下是ObjectiveC中的类。类其实是OOP中的一个概念,概念上简单来讲类是它是一组关系密切属性的集合,所谓的关系就是对现实事物的抽象。 上面提到的关系包括很多种,比如has a, is a,has some等&…...
Qt 总结
由于工作需要用到Qt。把过程中学习到的东西记录下来,希望能帮到他人和将来的自己。 由于需要快速实现需求,所以对Qt只是使用,并没有对原理的深入理解。 故此文只适合入门,不适合深入学习Qt。 文章目录 安装&维护示例&教…...
中间件复习之-RPC框架
什么是RPC框架? RPC(Remote Procedure Call):远程过程调用。当多个应用部署在多个服务器上时,由于他们不在一个内存空间上,因此需要网络来进行通信,而RPC允许它像调用本地方法一样调用远程服务。 RPC原理 服务消费方通过RPC客户…...
AcWing 787. 归并排序——算法基础课题解
AcWing 787. 归并排序 文章目录 题目描述CGo模板 题目描述 给定你一个长度为 n 的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有…...
力扣1379---找出克隆二叉树的相同节点(Java、DFS、简单题)
目录 题目描述: 思路描述: 代码: (1): (2): 题目描述: 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 ori…...
FLink学习(三)-DataStream
一、DataStream 1,支持序列化的类型有 基本类型,即 String、Long、Integer、Boolean、Array复合类型:Tuples、POJOs 和 Scala case classes Tuples Flink 自带有 Tuple0 到 Tuple25 类型 Tuple2<String, Integer> person Tuple2.…...
Failed to resolve import “Home/components/HomeNew.vue“. Does the file exist?
错误信息 [plugin:vite:import-analysis] Failed to resolve import "/apis/home.js" from "src/views/Home/components/HomeNew.vue". Does the file exist? 错误原因 路径错误 解决方法...
《价值》-张磊-高瓴资本-3-建立人脉和信任;顺应趋势,把握机遇;
第三章 价值投资初试炼 2005.6.1 创办高瓴资本 许多人问我为什么一直在创业,其实我倒没想到自己非要创业成功不可,只是觉得一定要做点事,做点有意义的事。归根到底,可能是“爱折腾,不满足现状,爱挑战自己”…...
游戏引擎中的物理应用
一、 角色控制器 Character Controller和普通的动态对象(Dynamic Actor )是不同的,主要的三个特点是: 它拥有可控制的刚体间的交互假设它是有无穷的摩擦力(可以站停在位置上),没有弹性加速和刹车几乎立即…...
复现k8s黄金票据学习
1.什么是黄金票据 在 Kubernetes 中,"黄金票据"并不是一个常见的术语。可能你想了解的是服务账户(Service Account)。服务账户是 Kubernetes 中用于身份验证和授权的一种机制。它们允许 Pods 或其他工作负载在 Kubernetes 集群中与…...
08-JavaScript BOM定时器及JS动画
1. 设置定时器 1.1设置超时定时器 超时调用需要使用window对象的setTimeout()方法,该方法接受两个参数:调用函数或计算表达式和以毫秒为单位的时间(即在执行代码前需要等待多少毫秒)。 //setTimeout(callback, after) //callba…...
边缘计算盒子与云计算:谁更适合您的业务需求?
边缘计算盒子和云计算,这两个概念听起来可能有点复杂,但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢?咱们来详细说说。 边缘计算盒子,就像是个小型的数据处理中心,放在离你业务现场比较近的地方。它…...
浅聊什么是Redis?
需求:MySQL面临大量的查询,即读写操作,因此类比CPU,给数据加缓存,Redis诞生。应用程序从MySQL查询的数据,在Redis设置缓存(记录在内存中,无需IO操作),后再需要…...
java算法day43 | ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零
1049. 最后一块石头的重量 II 核心思想: 尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。 是不是感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。那么分成两堆石头,一堆石头的…...
练气第六天
问:ANR怎么分析? ANR问题,这其实是一个非常综合性的问题,因为anr会涉及CPU负载,内存空间大小,线程锁,GC回收,这里面每个点,都是非常考验我们基本功的。 分析ANR问题,需…...
认识 Redis 与 分布式
Redis 官网页面 Redis官网链接 Redis 的简介 Redis 是一个在内存中存储数据的中间件 一方面用于作为数据库,另一方面用于作为数据缓存,适用于分布式系统中 Redis 基于网络,进行进程间通信,把自己内存中的变量给别的进程…...
Linux初学(十二)AWK进阶
一、AWK 1.1 简介 AWK是Linux中重要的文本处理工具Linux三剑客只一处理的对象可以是一个具体的文件,也可以是一个命令的执行结果AWK按行读取文件,将每一行视为一条记录 案例一:获取系统中每个用户的uid 方法一:cat /etc/passwd |…...
文字识别 Optical Character Recognition,OCR CTC STN
文字识别 Optical Character Recognition,OCR 自然场景文本检测识别技术综述 将图片上的文字内容,智能识别成为可编辑的文本。 场景文字识别(Scene Text Recognition,STR) OCR(Optical Character Recognition, 光学字符识别)传统上指对输入扫描文档图像进行分析处理,识…...
四、MySQL读写分离之MyCAT
一、读写分离概述 1、什么是读写分离: 读写分离:就是将读写操作分发到不同的服务器,读操作分发到对应的服务器 (slave),写操作分发到对应的服务器(master) ① M-S (主从) 架构下&…...
通讯录项目实现
引言:通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。 目录 顺序表与通讯录的比较 各源文件文件大榄 Contact.c中通讯录相关函数的定义 初始化和销毁通讯录 添加联系人: 删除联系人…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
