黑马程序员—OC学习笔记—多文件、组合类的运用

———–Java培训、Android培训、IOS培训、.Net培训、期待与您交流!————
本节是个人学习过程中的笔记,供初学者一起学习,欢迎大家批评指正,留言参与讨论,谢谢。
本节内容,多文件、组合类的运用,代码如下:
Point2D.h

/*
设计一个类Point2D,用来表示二维平面中某个点
1> 属性
* double x
* double y

2> 方法
* 属性相应的setget方法
* 设计一个对象方法同时设置xy
* 设计一个对象方法计算跟其他点的距离
* 设计一个类方法计算两个点之间的距离

3> 提示
* C语言的math.h中有个函数:double pow(double n, double m); 计算nm次方
* C语言的math.h中有个函数:double sqrt(double n); 计算根号n的值(对n进行开根)
*/

#import <Foundation/Foundation.h>

// 类Point2D声明,用来表示二维平面中某个点

@interface Point2D : NSObject
{
    // 设置两个成员变量来表示点对象的横竖坐标值
    double _x;
    double _y;
}

// 为成员变量提供setget方法
- (void)setX: (double)x;
- (double)x;
// error: 遗忘从头文件开始,必须细心
- (void)setY: (double)y;
- (double)y;

// 设计一个对象方法同时设置xy
- (void)setX: (double)x AndY: (double)y;

// 设计一个对象方法计算跟其他点的距离
- (double)getDistanceBetweenOtherPoint: (Point2D*)p;

// 设计一个类方法计算两个点之间的距离
+ (double)getDistanceBetweenPointA: (Point2D*)pa AndPointB: (Point2D*)pb;

@end

Point2D.m

#import "Point2D.h"  // error: 类名都能写错,我该有多么奇葩

// 类Point2D的实现

#import <math.h>

@implementation Point2D
//@import <math.h>  // error 如此奇葩的问题都能犯,第一不是@,第二位置坑爹,看来@end ,自己手写还是很有必要地

// 为成员变量提供set和get方法
- (void)setX: (double)x
{
    _x = x;
}
- (double)x
{
    return _x;
}
// error:自己遗漏咯_y的set和get,一定得细心检查
- (void)setY: (double)y
{
    _y = y;
}
- (double)y
{
    return _y;
}


// 设计一个对象方法同时设置x和y
- (void)setX: (double)x AndY: (double)y
{
//    _x = x;
//    _y = y;
//
//    self -> _x = x;
//    self -> _y = y;

    //以上两种方式都可以,但是不能很好体现封装性,如果对设置的变量值有各种过滤条件,就会导致代码重复,所以,即使在类实现内部,其他方法中也尽量避免直接使用成员变量,用get和set封装之后,就需要执行封装思想。
//    [self x];
//    [self y];
// error: 上面的bug很隐蔽,把set函数竟然写成咯get,汗
    [self setX: x];
    [self setY: y];
}

// 设计一个对象方法计算跟其他点的距离
- (double)getDistanceBetweenOtherPoint: (Point2D*)p
{
    // 这里需要用到提示信息
    // C语言的math.h中有个函数:double pow(double n, double m); 计算n的m次方
    // C语言的math.h中有个函数:double sqrt(double n); 计算根号n的值(对n进行开根)

    // 首先计算两个点之间的坐标差
    double marginX = [self x] - [p x];
    double marginY = [self y] - [p y];

    // 计算坐标差的平方
    double marginXPF = pow(marginX, 2);
    double marginYPF = pow(marginY, 2);

    // 计算最终结果,与其他点的距离
    double distence = sqrt(marginXPF + marginYPF);

    return distence;
}

// 设计一个类方法计算两个点之间的距离
+ (double)getDistanceBetweenPointA: (Point2D*)pa AndPointB: (Point2D*)pb
{
    // 这个方法实现思路跟上面的方法一致,可以相互调用来实现,直接避免代码重构
    // 虽然这里是类方法的内部,但是参数全部是对象,所以可以调用成员方法

    //return [pa getDistanceBetweenPointA: pb]; //这种奇葩自杀递归循环,我也写得出来
    // error: 必须得承认,自动补充完整时,需要注意有相似的补充进去,正确地被你华丽丽的忽视咯。

    return [pa getDistanceBetweenOtherPoint: pb];
}

@end

// 完成一个类,需要自己测试下,这个类的实现是否完整,可以在类的实现部分写一个main函数去测试
// 但是考虑到多文件之间的协作,以及注释删除问题,建议还是单独写一个包含main函数的.m文件来测试。

Circle.h

/*

 设计一个类Circle,用来表示二维平面中的圆
 1> 属性
 * double _radius (半径)
 * Point2D *_point (圆心)

 2> 方法
 * 属性相应的set和get方法
 * 设计一个对象判断跟其他圆是否重叠(重叠返回YES,否则返回NO)
 * 设计一个类方法判断两个圆是否重叠(重叠返回YES,否则返回NO)

 */

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

// 设计的Circle类的声明
@interface Circle : NSObject
{
    // 成员变量,有半径和圆心,其中圆心是运用类的组合,直接使用Point2D类的对象
    double _radius;
    Point2D* _point;
}

// 属性相应的set和get方法
- (void)setRadius: (double)radius;
- (double)radius;

- (void)setPoint: (Point2D*)point;
- (Point2D*)point;

// 设计一个对象判断跟其他圆是否重叠(重叠返回YES,否则返回NO)
- (BOOL)isContactOtherCircle: (Circle*)c;

// 设计一个类方法判断两个圆是否重叠(重叠返回YES,否则返回NO)
+ (BOOL)isContactOfCircleA: (Circle*)a AndCircle: (Circle*)b;

@end

Circle.m

#import "Circle.h"


@implementation Circle

// 属性相应的set和get方法
- (void)setRadius: (double)radius
{
    _radius = radius;
}
- (double)radius
{
    return _radius;
}

- (void)setPoint: (Point2D*)point
{
    //[_point setX: [point x] AndY: [point y]]; // error: 这样写,完全是值传递,Circle对象本身还没有组合而来的Point2D对象,应该是用对象来填充,而不是拷贝外来对象的成员值
    _point = point;
}
- (Point2D*)point
{
    return _point;
}

// 设计一个对象判断跟其他圆是否重叠(重叠返回YES,否则返回NO)
- (BOOL)isContactOtherCircle: (Circle*)c
{
    // 算法思想,就是比较两个圆心的距离与半径之和的大小关系,距离小的话就是重叠
    // 首先计算出两个圆心间距离
    double distance = [_point getDistanceBetweenOtherPoint: [c point]];
    double sumRadius = _radius + [c radius];

    // Bool类型,可以直接用下面的表达式作为返回值
    return distance < sumRadius;
}

// 设计一个类方法判断两个圆是否重叠(重叠返回YES,否则返回NO)
+ (BOOL)isContactOfCircleA: (Circle*)a AndCircle: (Circle*)b
{
    // 又是经典的代码复用
    return [a isContactOtherCircle: b];
}
@end

Main.m

#import <Foundation/Foundation.h>
#import "Point2D.h" // error:不能自己的头文件,顺手也写成了尖括号
#import "Circle.h"

// 写一个函数,测试一下Point2D这个类的方法是否都实现
void testPoint2D()
{
    // 创建一个Point2D对象,并且对成员变量进行赋值
    Point2D* p = [Point2D new];
    [p setX: 2];
    [p setY: 2];

    // error:必须谨记,OC里面字符串的差别,@开头,NSLog函数不能用printf习惯去写
    NSLog(@"x = %.2f, y = %.2f",[p x], [p y]);
    // 赋值也可以使用一起赋值的方法,他们都需要测试一下
    [p setX: 3 AndY: 3];

    NSLog(@"x = %.2f, y = %.2f",[p x], [p y]);

    // 再创建一个Point2D对象,两个对象来测试计算距离的两个函数正确性
    Point2D* p1 = [Point2D new];
    [p1 setX: 6 AndY: 8];

    // 先测试对象方法
    double distence = [p getDistanceBetweenOtherPoint: p1];

    NSLog(@"点(%.2f, %.2f)与点(%.2f, %.2f)之间的距离为:%.2f",[p x], [p y],[p1 x], [p1 y],distence);

    // 再测试类方法,虽然本质上面他们进行了代码复用,但是由于调用机制的不同,所以还是得测试一下。
    double distence1 = [Point2D getDistanceBetweenPointA: p AndPointB: p1];

    NSLog(@"点(%.2f, %.2f)与点(%.2f, %.2f)之间的距离为:%.2f",[p x], [p y],[p1 x], [p1 y],distence1);

}

void testCircle()
{
    // 测试Circle类,必须创建Circle对象,而Circle对象是由Point2D对象组合而成,所以必须在给Circle对象赋值之前完成Point2D对象的创建和初始化。
    // 创建第一个Circle对象c
    Circle* c = [Circle new];
    // 创建一个Point2D对象p,并且对成员变量进行赋值
    Point2D* p = [Point2D new];
    [p setX: 3 AndY: 3];
    // 为Circle对象c进行赋值初始化
    [c setRadius: 4];
    [c setPoint: p];

    // 测试一下,Circle对象初始化情况
    NSLog(@"圆心为(%.2f, %.2f),半径为%.2f",[[c point] x], [[c point] y],[c radius]);

    // 创建第二个Circle对象c
    Circle* c1 = [Circle new];
    // 创建一个Point2D对象p,并且对成员变量进行赋值
    Point2D* p1 = [Point2D new];
    [p1 setX: 3 AndY: 9.0];
    // 为Circle对象c进行赋值初始化
    [c1 setRadius: 2];
    [c1 setPoint: p1];

    NSLog(@"圆心为(%.2f, %.2f),半径为%.2f",[[c1 point] x], [[c1 point] y],[c1 radius]);

    // 计算两个Circle对象是否重叠
    // 先测试对象方法
    bool isContact = [c isContactOtherCircle: c1];
    //NSString* result = @(isContact == 1 ? "重合" : "相离");// 两种方式都行
    NSString* result = isContact == 1 ? @"重合" : @"相离";

    NSLog(@"两个圆重合的结果是:%@",result);
}


int main()
{
    // error:编译的时候,不能只处理主文件,从文件所有关联到得 .m文件都得照顾到
    testPoint2D();
    testCircle();
    return 0;
}

程序运行结果如下:
这里写图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OC(Objective-C)是一种面向对象的编程语言,它支持在中使用方法和block。方法是在中定义的方法,可以直接通过名来调用,而不需要实例化对象。而block是一种闭包,可以在代码中定义并传递给方法或函数,用于延迟执行特定的逻辑。 在OC中,可以使用方法来创建和操作的实例,例如通过一个工厂方法创建对象,或者在方法中实现一些与相关的逻辑。方法通常使用“+”符号进行声明和实现。 而block可以在方法中作为参数传递,也可以在方法中定义和使用。block可以捕获其所在作用域的变量,可以在方法内部延迟执行一段代码,也可以用于实现回调等功能。block的定义和使用使用“^(){}”语法。 方法和block可以结合使用,例如可以在方法中接受一个block作为参数,并在合适的时机调用该block,以实现一些灵活的逻辑。通过方法和block的组合,可以在OC中实现更加灵活和强大的功能,例如在异步操作中使用block来回调结果,或者在工厂方法中使用block来定制对象的初始化逻辑等。 总而言之,方法和block是OC中的两个重要特性,它们可以分别用于的操作和延迟执行逻辑,也可以结合使用以实现更加灵活的功能。在实际的OC开发中,方法和block通常会被广泛使用,可以帮助开发者更加简洁和灵活地实现代码逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值