代码之家  ›  专栏  ›  技术社区  ›  AConsumer

无法访问ruby中受保护的方法

  •  0
  • AConsumer  · 技术社区  · 6 年前

    我正在学习红宝石封装的概念。

    下面是示例代码,笔记本电脑从机器继承,我已经吃了一个受保护的方法(机器类),但不能通过笔记本电脑的实例访问。

    另外,我无法访问笔记本电脑的名为description的受保护方法。

    class Machine
    
      attr_accessor :name,:cost  generated
    
      protected
      def eat
        puts "machine don't eat"
      end
    
    end
    
    
    class Laptop < Machine
    
      private
      def ram
        return "4gb"
      end
    
      private
      def core
        return "i3"
      end
    
      protected
      def description
        puts "The laptop has #{ram} ram and it has #{core} core"
      end
    end
    
    laptop=Laptop.new
    laptop.name="hp_notebook_15_n205tx"
    laptop.cost =44000
    
    puts "laptop is a machine, & #{laptop.eat} "  #doesn't work
    puts "#{laptop.name} costs #{laptop.cost}"
    puts "#{laptop.description}"                  #doesn't work
    

    下面是我得到的错误:

    `<top (required)>': protected method `eat' called for #<Laptop:0x2ed3b68 @name="hp_notebook_15_n205tx", @cost=44000> (NoMethodError)
        from -e:1:in `load'
        from -e:1:in `<main>'
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   ptierno    6 年前

    受保护的方法只能由封装在类或子类本身中的方法调用,而不是直接从类/子类的实例调用。如果你想 eat 要从实例调用而不是将其公开或从其他公共方法调用的方法:

    [19] pry(main)> class Machine
    [19] pry(main)*   protected
    [19] pry(main)*   def eat
    [19] pry(main)*     puts "eating"
    [19] pry(main)*   end
    [19] pry(main)* end
    :eat
    [20] pry(main)> class Laptop < Machine
    [20] pry(main)*   def chow
    [20] pry(main)*     self.eat
    [20] pry(main)*   end
    [20] pry(main)* end
    :chow
    [21] pry(main)> l = Laptop.new
    #<Laptop:0x007f9c92b5c968>
    [22] pry(main)> l.chow
    eating
    nil
    
        2
  •  0
  •   zeitnot    6 年前

    除了动态调度之外,您不能从Ruby外部获得受保护的或私有的方法。我的意思是 laptop.eat 但会引起例外, laptop.send(:eat) 将使运行方法。这是动态调度。

        3
  •  0
  •   AConsumer    6 年前
    • 方法和常量的可见性或访问权限可以设置为 方法公共的、私有的或受保护的。
    • ruby不允许您访问或更改实例变量表单 课外活动。为了克服这个问题,您必须使用访问器 方法
    • 只能在类内调用私有方法,而不是从 类本身的实例也不与self关键字一起使用

    • 受保护的方法只能由封装在类或子类本身中的方法调用,而不是直接从类/子类的实例调用。

       class Machine
        attr_accessor :name,:cost
      
        # All the methods below the  protected keyword will be protected
        protected
      
        def eat
          puts "machine don't eat"
        end
      
        def sleep
          puts "machine don't sleep"
        end
      
      end
      
      machine=Machine.new
      machine.name ="Keyword"
      puts "The name of the machine is #{machine.name}"
      
      # NoMethodError  because of accessing the protected methods via an object of Machine
      # puts machine.eat
      # puts machine.sleep
      
      class Laptop < Machine
      
        # All the method below the private keyword be will private
        private
      
        def ram                                 # private method
          return "4gb"
        end
      
        def core                                # private method
          return "i3"
        end
      
        # all the methods below the protected keyword will be protected
        public
      
        def description
          puts "The laptop has #{ram} ram and it has #{core} core"
        end
      
        def laptopActivity
          eat
          sleep
        end
      end
      
      laptop=Laptop.new
      laptop.name="hp_notebook_15_n205tx"
      laptop.cost =44000
      
      # puts "laptop is a machine, & #{laptop.eat}"   NoMethodError coz trying to access protected method through the object
      puts "#{laptop.name} costs #{laptop.cost}"     #accessing public method of Machine through the laptop object
      puts "#{laptop.description}"                   # made description public ( description method calls private method of laptop class)
      puts laptop.laptopActivity                     # calling protected methods of parent class (inheritance)