【OC学习-14】多态是什么?看父类方法在子类中复写产生的效果

什么是多态?

官方说法:同一接口,不同实现方法。其实大白话就是(以父类和子类为例,实际上可以不限于这种关系):父类有一个方法(函数),派生出得很多子类也有这个方法(函数),但是每个方法(函数)里内容不同。当然方法相同是指这个方法的名字、返回值类型、参数个数类型都一样。

直接上例子:我们创建一个父类ASShape有个draw方法,派生出三个子类ASCircle,ASRectangle、ASTriangle各自也有一个draw,当然每个draw里内容不同,就是实现输出一个句子。

(1)先创建一个父类:

//ASShape.h文件
#import <Foundation/Foundation.h>
@interface ASShape : NSObject
-(void)draw;
@end

//ASShape.m文件
#import <Foundation/Foundation.h>
@interface ASShape : NSObject
-(void)draw;
@end

(2)再创建三个子类,draw方法相同,里面内容不同,以下只列出一个,另外的ASCircle类和ASRectangle类自己冥想去。

//ASTriangle.h文件,继承ASShape类
#import "ASShape.h"
@interface ASTriangle : ASShape
-(void)draw;
@end

//基本和父类ASShape的draw类似,只是内容输出不同
#import "ASTriangle.h"
@implementation ASTriangle
-(void)draw{
    NSLog(@"triangle:draw");
}
@end

(3)再创建一个ASPerson类,借助这个类的paint方法把上面的类当做参数,并调用它们各自的draw方法

//ASPerson.h,要使用ASShape类,因为下面会用它创建对象
#import <Foundation/Foundation.h>
@class ASShape;
@interface ASPerson : NSObject
-(void)paint:(ASShape *)aShape;
@end

//ASPerson.m,需要导入各个头文件,不然它们各自的draw函数根本不能会调出来
#import "ASPerson.h"
#import "ASShape.h"
#import "ASCircle.h"
#import "ASRectangle.h"
#import "ASTriangle.h"
@implementation ASPerson
-(void)paint:(ASShape *)aShape{
    [aShape draw];
}
@end

(4)最后在main.m里面创建对象,并用这个对象去调用paint方法,由于paint方法的参数是ASShape类的对象,本应该调用ASShape类对象自己的draw函数,但是因为我们把ASShape子类实例化的对象当做参数传递给了paint,所以它们调用的就是各个子类自己的draw函数。这应该就是因为draw是多态的,所以调用哪个取决于你传递的参数吧。

#import <Foundation/Foundation.h>
#import "ASPerson.h"
#import "ASShape.h"
#import "ASCircle.h"
#import "ASRectangle.h"
#import "ASTriangle.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        ASPerson * person=[[ASPerson alloc]init];
        ASCircle * circle=[[ASCircle alloc]init];
        ASRectangle * rec=[[ASRectangle alloc]init];
        ASTriangle * tri=[[ASTriangle alloc]init];
        [person paint:circle];
        [person paint:rec];
        [person paint:tri];
    }
    return 0;
}

(5)运行结果

circle:draw
rectangle:draw
triangle:draw

注意事项:

a:把父类指定换成id通用指针,运行结果一样OK。id通用指针可以指向任何对象,指向谁就调用谁的方法(函数)。

@implementation ASPerson
-(void)paint:(id)aShape{
    [aShape draw];
}
@end

b:我们创建一个不集成ASShape的类叫ASExp,也给它定义一个draw方法。和上面操作步骤一致,先实例化一个对象对来,然后如下,发现结果也能输出,也就是说,这个多态并非一定要是父类和子类之间。

ASExp * exp=[[ASExp alloc]init];
[person paint:exp];

如果没有这个父类和子类的限制,或许能更明白多态,多态其实就是一个方法(函数)在不同类中写了很多个,具体执行时候,传递的时哪个类对象,就调用那个类对象的方法(函数)。

时间: 2024-11-08 20:10:07

【OC学习-14】多态是什么?看父类方法在子类中复写产生的效果的相关文章

java多态,如何理解父类引用指向子类对象

摘录 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new Cat(); 实例化一个Cat的对象,这个不难理解. 但当我这样定义时:   Animal a = new Cat(); 表示定义了一个Animal类型的引用,指向新建的Cat类型的对象.由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的. 那么这样做有什么意义呢?因为子类是对父类的一个改进

JavaSE8基础 多态 子类重写了父类的普通方法 父类引用调用子类中重写的方法

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        代码: class Father { public int num = 1; public void sayHello() { System.out.println("hello"); } public static void staticFun() { System.out.println("s

学习java线程状态和看懂thread dump文件中的线程信息

线程的状态是一个很重要的东西,因此thread dump中会显示这些状态,通过对这些状态的分析,能够得出线程的运行状况,进而发现可能存在的问题.线程的状态在Thread.State这个枚举类型中定义: public enum State { /** * Thread state for a thread which has not yet started. */ NEW, /** * Thread state for a runnable thread. A thread in the runn

swift 学习- 14 -- 继承

// 一个类可以继承另一个 类的方法, 属性和其他特征, 当一个类继承其他类时, 继承类叫子类, 被继承类叫父类 或 (超类), 在 Swift 中, 继承是区分 [类] 和其他类型的 一个基本特征 // 在 Swift 中, 类可以调用和访问超类的方法, 属性 和 下标, 并且可以重写这些方法, 属性 和 下标来优化或修改他们的行为 // Swift 会检查你的重写定义在超类中是否有匹配的定义, 一次确保你的重写行为是正确的 // 可以为类中继承来的属性添加属性观察器, 这样一来, 当属性值改

理解父类引用指向子类对象

java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new Cat(); 实例化一个Cat的对象,这个不难理解. 但当我这样定义时:   Animal a = new Cat(); 这代表什么意思呢? 很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象.由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向C

C# 继承实现父类方法、重写、重载

继承是派生类(子类)去实现(重写<override>.重构<new>)基类(父类)的方法或属性.从而获取在派生类中要实现的功能. 子类调用父类构造方法,在父类中有个实现姓名和年龄的构造方法但是中子类也要实现这样的功能这时子类不用再次去写这个功能只要去调用父类的功能即可. public class Person { private string _name = null; private int _age = 0; public Person(string name, int age

java中子类覆盖父类方法所必须满足的条件

一.描述 子类重写(覆盖)父类的方法必须满足的条件: 1.父类中的方法在子类中必须可见,即子类继承了父类中的该方法(可以显式的使用super关键字来访问父类中的被重写的方法), 如果父类中的方法为private类型的,那么子类则无法继承,也无法覆盖. 2.子类和父类的方法必须是实例方法,如果父类是static方法而子类是实例方法,或者相反都会报错. 如果父类和子类都是static方法,那么子类隐藏父类的方法,而不是重写父类方法. 3.子类和父类的方法必须要具有相同的函数名称.参数列表,并且子类的

(转载)OC学习篇之---类的三大特性:封装,继承,多态

之前的一片文章介绍了OC中类的初始化方法和点语法的使用,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今天就来看一下OC中类的三大特性: 一.封装 学习过Java中类的同学可能都知道了,封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能,Java中有四种访问权限修饰符:public,default,protected,private,访问权限一次递减的,这样我们在定义类的时

OC学习篇之---类的三大特性(封装,继承,多态)

之前的一片文章介绍了OC中类的初始化方法和点语法的使用:http://blog.csdn.net/jiangwei0910410003/article/details/41683873,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今天就来看一下OC中类的三大特性: 一.封装 学习过Java中类的同学可能都知道了,封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能,Java