Point2D.h
/*
设计一个类Point2D,用来表示二维平面中某个点
1> 属性
* double x
* double y
2> 方法
* 属性相应的set和get方法
* 设计一个对象方法同时设置x和y
* 设计一个对象方法计算跟其他点的距离
* 设计一个类方法计算两个点之间的距离
3> 提示
* C语言的math.h中有个函数:double pow(double n, double m); 计算n的m次方
* C语言的math.h中有个函数:double sqrt(double n); 计算根号n的值(对n进行开根)
*/
#import <Foundation/Foundation.h>
// 类Point2D声明,用来表示二维平面中某个点
@interface Point2D : NSObject
{
// 设置两个成员变量来表示点对象的横竖坐标值
double _x;
double _y;
}
// 为成员变量提供set和get方法
- (void)setX: (double)x;
- (double)x;
// error: 遗忘从头文件开始,必须细心
- (void)setY: (double)y;
- (double)y;
// 设计一个对象方法同时设置x和y
- (void)setX: (double)x AndY: (double)y;
// 设计一个对象方法计算跟其他点的距离
- (double)getDistanceBetweenOtherPoint: (Point2D*)p;
// 设计一个类方法计算两个点之间的距离
+ (double)getDistanceBetweenPointA: (Point2D*)pa AndPointB: (Point2D*)pb;
@end
Point2D.m
#import "Point2D.h"
// 类Point2D的实现
#import <math.h>
@implementation Point2D
// 为成员变量提供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
{
// 计算两个点之间的坐标差
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"
#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;
}
程序运行结果如下:
网友评论