zoukankan      html  css  js  c++  java
  • ruby的继承到底可以继承哪些东西

    1.先看私有方法能否被继承

    class A
        @@name="Anleb"
        
        def ask 
            puts @@name
        end
        private :ask
    end
    a=A.new
    #a.ask
    a.send(:ask)
    
    class B < A
        
    end
    b=B.new
    #b.ask
    b.send(:ask)
    

     结论:对于private方法,是被继承的,类变量(类似于静态变量,属于所有实例),也是可以被继承的。

    2.看类的方法能否被继承
    题外话:private影响谁?

    class A
        private
        def self.ask
            puts "class method1"
        end
        class << self
            def play
                puts "class method2"
            end
        end
        def tell
            puts "instance methods"
        end
    end
    A.ask
    A.send(:ask)
    A.play
    A.send(:play)
    a=A.new
    #a.tell
    a.send(:tell)
    

     结论:可以看到Private只影响实例方法,对类的方法没有影响,要想设定类的private方法,必须在类的单件类中设置。如下

    class << self
            private
            def play
                puts "class method2"
            end
        end
    

     进入正题,类的方法是否能继承

    class A
        private
        def self.ask
            puts "class method1"
        end
        class << self
            private
            def play
                puts "class method2"
            end
        end
        def tell
            puts "instance methods"
        end
    
    end
    
    class B < A
        
    end
    B.ask
    B.send(:play)
    

     结论:类的方法也是能继承的,如果看过元编程应该知道B的祖先链:B-A-A的单件类-Object-Kernel-BaseObject

    3.类本身的实例变量是否能继承

    class A
        @name="Anleb"
        class << self
            attr_accessor :name
        end
    end
    p A.name
    class B < A
        
    end
    p B.name
    
    输出:
    Anleb
    nil
    

     结论:说明类的实例变量是不继承的,注意,这里要区别于 类的对象的实例变量。
    根据元编程的思路,就是:
    对象包含:
    对象对类的引用(指针)
    对象的实例变量
    对象的object_id
    对象的状态tainted和frozen状态

    类包含:
    实例的方法
    类变量

    因为对象的实例变量是存在于对象中的,所有其他的对象无法从类中获得这个实例变量。
    4.super

    class A
        attr_accessor :ob_name
        def initialize
            @ob_name="Anleb"
        end
    end
    p A.new.ob_name
    class B < A
        attr_accessor :ob_id
        def initialize
            @ob_id=1
        end
    end
    p B.new.ob_name
    输出:
    Anleb
    nil #这里是Nil,是因为继承了attr_accessor生成的魔法方法
    

     说明:这里不要误解了,都说是覆盖了父类A的initialize方法,其实不是的,因为对象调用方法的模式是:先向右-找到自己的类,然后再向上查找自己的祖先类。
    这里没有调用父类A的初始化方法,是因为,先找到了自己类B的初始化方法。

    如果也继承父类的同名方法呢?利用super

    class A
        attr_accessor :ob_name
        def initialize
            @ob_name="Anleb"
        end
        def ask
            puts "A methods"
        end
    end
    p A.new.ob_name
    class B < A
        attr_accessor :ob_id
        def initialize
            @ob_id=1
            super
        end
        def ask
            puts "B methods"
            super
        end
    end
    p B.new.ob_name
    B.new.ask
    
    输出:
    "Anleb"
    "Anleb"
    B methods
    A methods
    
  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/IAmBetter/p/2963680.html
Copyright © 2011-2022 走看看