zoukankan      html  css  js  c++  java
  • 解决重写父类的方法且不会影响继承的子类的问题

    解决重写父类的方法且不会影响继承的子类的问题

    基类的方法被所有继承的子类继承,是不应该被修改的,如果继承的子类重写了基类的方法,那么,再从这个子类派生出子类的话,这个派生的子类接口已经破坏掉了统一的接口.

    但有时候,我们需要一个子类能扩展基类的方法,但又不想破坏这个统一的接口,这时候,哥就来教你既能扩展功能,又能保证接口的统一性:)

    首先做几个实验验证:

    提供的源码如下:

    A类  B类  C类  (B类继承于A类,C类继承于B类)

    //
    //  A.h
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface A : NSObject
    
    - (void)info;
    
    @end
    //
    //  A.m
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "A.h"
    
    @implementation A
    
    - (void)info
    {
        NSLog(@"%@ message:%@", self, @"A");
    }
    
    @end
    //
    //  B.h
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "A.h"
    
    @interface B : A
    
    - (void)info;
    
    @end
    //
    //  B.m
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "B.h"
    
    @implementation B
    
    - (void)info
    {
        [super info];
        NSLog(@"%@ message:%@", self, @"B");
    }
    
    @end
    //
    //  C.h
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "B.h"
    
    @interface C : B
    
    - (void)info;
    
    @end
    //
    //  C.m
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "C.h"
    
    @implementation C
    
    - (void)info
    {
        [super info];
        NSLog(@"%@ message:%@", self, @"C");
    }
    
    @end

    测试的源码如下:

    //
    //  RootViewController.m
    //  Super
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "A.h"
    #import "B.h"
    #import "C.h"
    
    
    @interface RootViewController ()
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        A *a = [A new];
        B *b = [B new];
        C *c = [C new];
        
        [a info];
        NSLog(@"
    ===========
    ");
        [b info];
        NSLog(@"
    ===========
    ");
        [c info];
    }
    
    @end

    打印结果:

    2014-08-16 09:48:13.556 Super[23845:60b] <A: 0xa142620> message:A
    2014-08-16 09:48:13.557 Super[23845:60b]
    ===========
    2014-08-16 09:48:13.557 Super[23845:60b] <B: 0xa142f00> message:A
    2014-08-16 09:48:13.557 Super[23845:60b] <B: 0xa142f00> message:B
    2014-08-16 09:48:13.558 Super[23845:60b]
    ===========
    2014-08-16 09:48:13.558 Super[23845:60b] <C: 0xa142fd0> message:A
    2014-08-16 09:48:13.558 Super[23845:60b] <C: 0xa142fd0> message:B
    2014-08-16 09:48:13.559 Super[23845:60b] <C: 0xa142fd0> message:C

    为什么C对象会执行了3次呢?请看下图:

    因为,重写了父类的方法时是需要先调用父类方法的,毕竟,有时候,父类的方法进行了一些配置,子类才能用,所有,通过 super 调用了父类的方法,一级一级到达了基类A了.

    我们要达到什么样的效果呢?

    我们需要达到的效果是:让子类C不会调用A类与B类的打印语句

    修改成如下形式:

    打印结果:

    2014-08-16 10:07:57.270 Super[23966:60b] <A: 0x8d17200> message:A
    2014-08-16 10:07:57.272 Super[23966:60b]
    ===========
    2014-08-16 10:07:57.272 Super[23966:60b] <B: 0x8d17aa0> message:B
    2014-08-16 10:07:57.272 Super[23966:60b]
    ===========
    2014-08-16 10:07:57.273 Super[23966:60b] <C: 0x8d17b70> message:C

    为什么要这么做呢?

    其实,这就是软件设计中的不破坏原始接口的用处哦:),需要自己去慢慢体会.

  • 相关阅读:
    如何解决无法成功git commit 和git push
    orleans 项目调试注意
    silo 主机 配置
    asp.net core 项目引用包版本问题
    C# async 方法怎么被正确的消费 (新篇)
    C# 虚方法 复习
    C# dynamic 适用场景进一步说明
    [MySQL]
    C# Subject 观察者模式
    C# 协变与逆变
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3916095.html
Copyright © 2011-2022 走看看