[黑马程序员]11[OC语言]圆,点问题, OC的面向对象程序设计思想和类封装

来源:互联网 发布:c语言经典第五版pdf 编辑:程序博客网 时间:2024/06/16 13:45

------- android培训、java培训、IOS培训、期待与您交流! ----------


前言:在学完OC的基本语法与核心语法后,我们发现OC的基本学习内容都是语法和用法,以及相应地应用. 我们知道, 作


为面向过程的C语言,经常要深入到具体的实现过程中去考虑设计功能的实现,而OC作为面向对象语言,它是专门体现面


向对象思想的,又是如何在实际开发应用中体现出来的呢,我们这里引入一个OC类的设计习题

 

正文:


OC开发技巧部分—习题06:


// 设计一个类circle,用来表示二维平面中得圆

// 1>属性

// double radius (半径)

// Point2D *point (圆心)

 

// 2>方法

// 属性相应地setget方法

// 设计一个对象判断跟其他圆是否重叠(重叠返回YES,否则返回NO)

//设计一个类方法判断两个圆是否重叠(重叠返回YES,否则返回NO)

 

我们看到,在这里,需要设计的类circle里面还包含了一个类point,这种一个类中包含了多个类成员变量的情况也是我们今


后开发所经常要遇到的,那么在这个简单地单类包含情况下,我们的类设计该如何实现了

 


为了实现所需类Circle的需求,我们首先需要设计好一个point类:



这个类应该拥有如下属性:

//1>属性

//double x

//double y

 

// 2>方法

// 属性相应的setget方法

// 设计一个对象方法同时设置xy

// 设计一个对象方法计算跟其他点得距离

//设计一个类方法计算两个点之间的距离

 

我们根据所需,根据我们在OC基本语法和核心语法里所学习的内容对point进行类设计

 

#import <Foundation/Foundation.h>

#import <math.h>

 

@interface Point2D :NSObject

{

    double _x;

    double _y;

}

 

// x值的gettersetter

- (void)setX:(double)x;

- (double)x;

 

// y值的gettersetter

- (void)setY:(double)y;

- (double)y;

 

// 设计一个对象方法同时设置xy

- (void)setX:(double)x andY:(double)y;

 

// 设计一个对象方法计算跟其他点得距离

- (double)distanceWithOther:(Point2D *)other;

 

// 设计一个类方法计算两个点之间的距离

+ (double)distanceBetweenPoint1:(Point2D *)Point1 andPoint2:(Point2D *)Point2;

 

@end

 

@implementation Point2D

 

// x值的gettersetter

- (void)setX:(double)x

{

    _x = x;

}

 

- (double)x

{

    return_x;

}

 

// x值的gettersetter

- (void)setY:(double)y

{

    _y = y;

}

 

- (double)y

{

    return_y;

}

 

// 设计一个对象方法同时设置xy

- (void)setX:(double)x andY:(double)y

{

    //   _x = x;

    //   _y = y;

    //建议这样写,因为可能会有过滤

    [selfsetX:x];

    [selfsetY:y];

}

 

// 设计一个对象方法计算跟其他点的距离

- (double)distanceWithOther:(Point2D *)other

{

    return [Point2DdistanceBetweenPoint1:selfandPoint2:other];

}

 

// 设计一个类方法计算两个点之间的距离

+ (double)distanceBetweenPoint1:(Point2D *)Point1 andPoint2:(Point2D *)Point2

{

    double xDelta = [Point2x] - [Point1x];

   

    double xDeltaPF =pow(xDelta,2);

   

    double yDelta = [Point2y] - [Point1y];

   

    double yDeltaPF =pow(yDelta,2);

   

    returnsqrt(xDeltaPF + yDeltaPF);

}

 

@end

 

点设计这部分最值得注意的就是两个计算方法是可以相互调用的,因此只需要写一个方法的实现即可,避免重复累赘代


 

int main()

{

    Point2D *p1 = [Point2Dnew];

 

    Point2D *p2 = [Point2Dnew];

 

    [p1 setX:0.0 andY:1.0];

 

    [p2 setX:3.0 andY:5.0];

 

    double dis = [Point2DdistanceBetweenPoint1:p1andPoint2:p2];

 

    NSLog(@"%f",dis);

 

    double dis2 = [p1distanceWithOther:p2];

 

    NSLog(@"%f",dis2);

 

    return0;

}

 

建立一个主函数对这个类以及类的实现进行测试,满足要求,那么这个point类就作为一个独立的对象以及实现好了

 


接下来完成Circle类的设计

 

////

@interface Circle :NSObject

{

    // double radius (半径)

    double _radius;

    // Point2D *point (圆心)

    Point2D *_point;

}

 

//半径的settergetter

- (void)setRadius:(double)radius;

- (double)radius;

 

//圆心的settergetter

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

- (Point2D *)point;

 

//判定是否重叠

//返回值是bool类型的,方法名一般都以is开头

- (BOOL)isInteractWithOther:(Circle *)other;

 

+ (BOOL)isInteractBetweenCircle1:(Circle *)c1 andCircle2:(Circle *)c2;

 

@end

 

@implementation Circle

 

//半径的settergetter

- (void)setRadius:(double)radius

{

    _radius = radius;

}

- (double)radius

{

    return_radius;

}

 

//圆心的settergetter

- (void)setPoint:(Point2D *)point

{

    _point = point;

}

- (Point2D *)point

{

    return_point;

}

 

- (BOOL)isInteractWithOther:(Circle *)other;

{

    //如果圆心距离<半径和.重叠

    Point2D *p1 = [selfpoint];

    Point2D *p2 = [otherpoint];

   

    //圆心距离

    double distance = [p1distanceWithOther:p2];

   

    //半径和

    double radiusSum = [selfradius] + [otherradius];

   

    //判断后返回值

    return distance < radiusSum;

}

 

+ (BOOL)isInteractBetweenCircle1:(Circle *)c1 andCircle2:(Circle *)c2

{

    return  [c1isInteractWithOther: c2];

}

 

@end

 

Circle类的设计实现,除了关于方法实现上与point一样根据相互调用来避免重复累赘代码这点需要注意外,最重要的一


点,就是对于成员变量point的包含,以及它的set和get方法.在Circle类的设计过程中,我们把point当做是一个普通的成员


变量,除了类型不同,与普通的基本数据类型变量没有任何区别,这也是OC的面向对象思想的体现之一.OC并不要求知道


类中的包含类是如何实现的,各个功能的实现封装在不同的对象中,对于每一个对象,其他所有的对象都是封装好的只有


功能属性的简单对象.

 

建立新的主函数,对我们实现好的类设计进行测试

int main()

{

    //圆对象c1

    Circle *c1 = [Circlenew];

   

    //创建圆心对象(点对象)

    Point2D *p1 = [Point2Dnew];

    [p1 setX:10 andY:15];

   

    //先设置圆心

    [c1 setPoint: p1];

   

    [[c1 point] setX:15];

   

    //半径

    [c1 setRadius:2];

   

   

    //圆对象c2

    Circle *c2 = [Circlenew];

   

    //创建圆心对象(点对象)

    Point2D *p2 = [Point2Dnew];

    [p2 setX:12 andY:19];

   

    //先设置圆心

    [c2 setPoint:p2];

   

    //半径

    [c2 setRadius:6];

   

    BOOL b0 =[c1isInteractWithOther:c2];

   

    BOOL b1 =[CircleisInteractBetweenCircle1:c1andCircle2:c2];

   

    NSLog(@"%d",b0);

   

    NSLog(@"%d",b1);

   

    return0;

}

 

满足要求.这个练习充分体现了OC中类的封装和调用关系

 


而在实际开发过程中,一旦像这样需要包含和引用的类超过一定的数量,写在同一个文件中,就会写得相当复杂,降低程序


的可读性,因此我们需要像c语言里那样对不同功能的文件进行独立封装.

 


对圆,点题的类进行独立封装

 

1.Point2D.m :Point2D这个类的声明与实现  编译成功->Point2D.o文件(然而没有主函数)->无法生产可执行文件

 


2.Circle.m : Circle这个类的声明和实现 (+Point2D的声明和实现)  编译不成功(缺乏Point*_point的说明) ->预处理位置

加上#import "Point2D.m" ->编译成功->Circle.o文件(然而仍然没有主函数) ->无法产生可执行文件

 


3.main.m :main函数 预处理加上#import"Point2D.m""Circle.m"

 


这样很像c语言的多文件包含思想,然而实际中并不是这样做,因为Xcode在运行时会自动加载当前文件夹里所有的.m文

件,所以如果这样做会有很多的重复,由于重复定义而报错,那么该怎么办呢?

 


为了解决这个问题,引入c语言中的头文件概念,预处理里只引入.h文件,严禁引入.c和.m文件等源文件

 

把类同函数那样分拆成声明和实现,声明放在.h文件中,实现放在.m文件中,Point2D.m文件中加入预处理

#import"Point2D.h"  Circle.h的声明中加入预处理Point2D.h, Circle.m 文件中加入预处理Circle.h.  而主函数中加入预处

理两个头文件.

 

 

 定义一个类分为2个文件:.h声明文件, .m实现问价


 .h 成员变量,方法的声明


 .m 方法的实现

 

如果想使用某一个类,只需要#import类的.h文件即可
0 0
原创粉丝点击