黑马程序员_封装、继承、多态

本文介绍了面向对象编程中的三个核心概念:封装、继承和多态。封装是隐藏内部实现并稳定外部接口的过程;继承是从现有类继承功能并扩展它们的能力;多态允许父对象根据当前赋值的不同方式运作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


封装

封装是对象和类概念的主要特性。它是隐藏内部实现,稳定外部接口,可以看作是“包装”。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问

1.set方法

作用:设置成员变量,可以在方法中过滤一些不合理的值。

命名规范:方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写,形参名称不要跟成员变量同名


#import <Foundation/Foundation.h>

@interface Person : NSObject

{

   @private

    int  _age;

}

-(void)setAge:(int)age;

-(int)age;

@end

@implementation Person

- (void) setAge(int)age

{

    _age = age;

}

@end


2.get方法

作用:返回对象内部的成员变量

命名规范:get方法的名称一般就跟成员变量同名。

3.成员变量的命名规范

成员变量都以下划线 _ 开头

可以跟get方法的名称区分开

可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量


@implementation Car

- (void) setAge(int)age

{

    _age = age;

}

-(int)age{

  return _age;

}

@end


4.封装的好处

过滤不合理的值

屏蔽内部的赋值过程

让外界不必关注内部的细节

继承

面向对象编程 (OOP)语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,mike是一个人,jim 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person类,因为腿并不是一个人。


Cricle类和Rectangle类非常相似,具体如下:


@interface Circle : NSObject
{
    @private
    ShapeColor fillColor;
    ShapeRect bounds;
}
- (void) setFillColor : (ShapeColor)fillColor;
- (void) setBounds : (ShapeRect)bounds;
- (void) draw;
- (NSString *) colorName : (ShapeColor)colorName;
@end   //Circle

@interface Rectangle : NSObject
{
@private
    ShapeColor fillColor;
    ShapeRect bounds;
}
- (void) setFillColor : (ShapeColor)fillColor;
- (void) setBounds : (ShapeRect)bounds;
- (void) draw;
- (NSString *) colorName : (ShapeColor)colorName;
@end   //Rectangle

#import "Circle.h"

@implementation Circle
- (void)setFillColor:(ShapeColor)c
{
    fillColor = c;
}//  setFillColor
- (void)setBounds:(ShapeRect)b
{
    bounds = b;
}
- (NSString *) colorName : (ShapeColor)colorName
{
    switch (colorName) {
        case kRedColor:
            return @"red";
            break;
        case kGreenColor:
            return @"green";
            break;
        case kBlueColor:
            return @"blue";
            break;
    }
    return @"no clue";
}
-(void) draw
{
    NSLog(@"drawing a circle at (%d %d %d %d) in %@",
          bounds.x, bounds.y,
          bounds.width, bounds.height,
          [self colorName : fillColor]);
}
@end

#import "Rectangle.h"

@implementation Rectangle
- (void)setFillColor:(ShapeColor)c
{
    fillColor = c;
}//  setFillColor
- (void)setBounds:(ShapeRect)b
{
    bounds = b;
}
- (NSString *) colorName : (ShapeColor)colorName
{
    switch (colorName) {
        case kRedColor:
            return @"red";
            break;
        case kGreenColor:
            return @"green";
            break;
        case kBlueColor:
            return @"blue";
            break;
    }
    return @"no clue";
}
-(void) draw
{
    NSLog(@"drawing a rect at (%d %d %d %d) in %@",
          bounds.x, bounds.y,
          bounds.width, bounds.height,
          [self colorName : fillColor]);
}
@end


两个类的setFillColor:和setBounds:方法的实现完全相同而draw方法的实现却不同。

创建一个Shape类,让Cricle类和Rectangle继承它

@interface Shape : NSObject
{
    @private
    ShapeColor fillColor;
    ShapeRect bounds;
}
- (void) setFillColor : (ShapeColor)fillColor;
- (void) setBounds : (ShapeRect)bounds;
- (void) draw;
- (NSString *) colorName : (ShapeColor)colorName;
@end   //Shape

@implementation Shape
- (void)setFillColor:(ShapeColor)c
{
    fillColor = c;
}//  setFillColor
- (void)setBounds:(ShapeRect)b
{
    bounds = b;
}
- (NSString *) colorName : (ShapeColor)colorName
{
    switch (colorName) {
        case kRedColor:
            return @"red";
            break;
        case kGreenColor:
            return @"green";
            break;
        case kBlueColor:
            return @"blue";
            break;
    }
    return @"no clue";
}
-(void) draw
{

}
@end






让两个子类去继承Shape类,并且重写draw方法

@interface Circle : Shape
@end   //Circle
@interface Rectangle : Shape
@end   //Rectangle
@implementation Circle
-(void) draw
{
    NSLog(@"drawing a circle at (%d %d %d %d) in %@",
          bounds.x, bounds.y,
          bounds.width, bounds.height,
          [self colorName : fillColor]);
}
@end
@implementation Rectangle
-(void) draw
{
    NSLog(@"drawing a rect at (%d %d %d %d) in %@",
          bounds.x, bounds.y,
          bounds.width, bounds.height,
          [self colorName : fillColor]);
}
@end

超类(superclass)是继承的类。Circle的超类是Shape,Shape的超类是NSObject。

父类(parent class)是超类的另一种表达方式。例如,Shape是Rectangle的父类。

子类(subclass)是执行继承的类。Circle是Shape的子类,而Shape又是NSObject的子类

孩子类(child class)是子类的另一种表达方式。Circle是Shape的孩子类。

如果想改变方法的实现,需要重写继承的方法。Circle具有自己的draw方法,因此我们说他重写了draw方法。


多态

多态性(polymorphism)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。不同对象以自己的方式响应相同的消息的能力叫做多态。
1.没有继承就没有多态
2.代码的体现:父类类型的指针指向子类对象
3.好处:如果函数、方法参数中使用的是父类类型,可以传入父类、子类对象
4.局限性:
1>父类类型的变量 不能 直接调用子类特有的方法,如果一定要调用,必须强转为子类类型变量后,才能直接调用子类特有的方法
2>调用方法时会检测对象的真实形象
3>不允许子类指针指向父类对象
3>如果参数中使用的是父类类型,可以传入父类、子类对象

覆盖(override),是指子类重新定义父类的虚函数的做法。
重载(overload),是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.youkuaiyun.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值