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
    
  • 相关阅读:
    VueRouter-编程式导航
    VueRouter-路由嵌套
    ubuntu安装qt时编译出现cstddef:50:10: fatal error: 'stddef.h' file not found
    六种常用位操作运算符原理及用途
    C语言编写程序的大小端问题
    linux系统中运行node进程,无法杀死进程
    满足客户的特殊需求,特殊轮播图非常规轮播图
    什么?你还不会通过纯js提交表单?
    什么?你还不会身份证号码验证?最全的身份证正则验证js
    什么!你想要封装好的ajax
  • 原文地址:https://www.cnblogs.com/IAmBetter/p/2963680.html
Copyright © 2011-2022 走看看