FJShape.h
#import <Foundation/Foundation.h>
//继承 is-a 关系
//记住:没有is-a关系的两个类一定不能写成继承
/**平面上的几何图形*/
@interface FJShape : NSObject
/**横坐标*/
@property (nonatomic,assign) int x;
@property (nonatomic,assign) int y;
/**颜色*/
@property (nonatomic,copy) NSString *color;
/**线条粗细*/
@property (nonatomic,assign) int lineWidth;
/**初始化方法*/
-(instancetype) initWithX :(int) x y:(int) y;
- (void) draw;
- (double) perimeter;
- (double) area;
@end
FJShape.m
#import "FJShape.h"
@implementation FJShape
- (instancetype)initWithX:(int)x y:(int)y{
// @throw [NSException exceptionWithName:@"" reason:@"unknown " userInfo:nil];
if(self = [super init]){
_x = x;
_y = y;
}
return self;
}
- (void)draw{
}
- (double)perimeter{
return 0;
}
- (double)area{
return 0;
}
@end
FJCircle.h
#import "FJShape.h"
@interface FJCircle : FJShape
@property (nonatomic,assign) double radius;//圆与其他图形的区别在于他有半径
//所以要在这里单独写一个属性radius半径
+ (instancetype) circleWithX:(int) x y:(int) y;
@end
FJCircle.m
#import "FJCircle.h"
@implementation FJCircle
+ (instancetype) circleWithX:(int)x y:(int)y{
return [[self alloc] initWithX:x y:y];
}
- (void)draw{
NSLog(@"○");
}
- (double)perimeter{
return 2*M_PI*_radius;
}
- (double)area{
return M_PI*_radius*_radius;
}
@end
FJRectangle.h
#import "FJShape.h"
@interface FJRectangle : FJShape
@property (nonatomic,assign) double width;
@property (nonatomic,assign) double height;
//矩形特有的长宽
+ (instancetype) rectangleWithX:(int) x y:(int) y;
@end
FJRectangle.m
#import "FJRectangle.h"
@implementation FJRectangle
+ (instancetype) rectangleWithX:(int)x y:(int)y{
return [[self alloc]initWithX:x y:y];
}
- (void)draw{
NSLog(@"☐");
}
- (double)perimeter{
return (_height +_width)*2;
}
- (double)area{
return _height *_width;
}
@end
FJTriangle.h
#import "FJShape.h"
@interface FJTritangle : FJShape
//三角形的三条边
@property (nonatomic,assign) double a;
@property (nonatomic,assign) double b;
@property (nonatomic,assign) double c;
+ (instancetype) triangelWithX:(int) x
y:(int) y;
//判断三条边是否可以构成一个合格的三角形
+ (BOOL) isValidWithEdgeA:(double) a edgeB:(double) b edgeC:(double) c;
@end
FJTriangle.m
#import "FJTritangle.h"
@implementation FJTritangle
+ (instancetype)triangelWithX:(int)x y:(int)y{
return [[self alloc] initWithX:x y:y];
}
//实现多态的第一步:
//重写override 父类有得方法子类重新给出自己的实现版本
- (void) draw{
NSLog(@"▷");
}
- (double)perimeter{
return _a + _b + _c;
}
- (double)area{
double p = (_a+_b+_c)/2;
return sqrt(p*(p-_a)*(p-_b)*(p-_c));
}
//该方法与对象无关。在创建对象之前就要调用的方法
//所以在设计上将其设计为类方法而不是对象方法
+ (BOOL)isValidWithEdgeA:(double)a edgeB:(double)b edgeC:(double)c{
{
return a+b>c && a+c>b &&b+c>a;
}
}
@end
main.m
#import <Foundation/Foundation.h>
#import "FJCircle.h"
#import "FJRectangle.h"
#import "FJTritangle.h"
//instance实例是对象object的别称
//encapsulation封装 inheritance继承 polymorphism:多态 OOP面向对象编程
int main(int argc, const char * argv[]) {
@autoreleasepool {
FJCircle *circle = [FJCircle circleWithX:5 y:10];
circle.radius = 10.2;
circle.color = @"red";
circle.lineWidth = 5;
FJRectangle *rectangle = [FJRectangle rectangleWithX:20 y:15];
rectangle.height = 50;
rectangle.width = 20;
rectangle.color = @"black";
rectangle.lineWidth = 2;
FJCircle *circle2 = [FJCircle circleWithX:2 y:8];
circle2.radius = 5.7;
circle2.color = @"purple";
circle2.lineWidth = 7;
FJTritangle *triangle = nil;
if ([FJTritangle isValidWithEdgeA:3 edgeB:4 edgeC:5]) {
triangle = [FJTritangle triangelWithX:1 y:1];
triangle.a=3;
triangle.b=4;
triangle.c=5;
}
NSArray *shapesArray = @[circle,circle2,rectangle,triangle];
//实现多态的第二步:对象造型
//用父类型指针指向子类对象:将能力多的对象当成能力少的对象使用没有问题
for (FJShape *shape in shapesArray) {
[shape draw];//同一个指针指向不同的子类对象,虽然调用的方法是一样的,
//但是结果不一样,因为子类对方法进行了不同的实现
//运行时才知道画圆还是画矩形,这就是运行时绑定(后绑定)
//也就是不看指针看对象(指针不能决定方法到底干什么)
NSLog(@"周长:%f\n",[shape perimeter]);//面向对象的精髓:多态
NSLog(@"面积:%f\n",[shape area]);//多态:不同的子类给出了不同的实现版本
NSLog(@"--------------");
}
}
return 0;
}