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

时间:2019-02-17 14:49:09

标签: ruby ruby-on-rails-4

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

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

此外,我无法访问笔记本电脑受保护的称为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>'

3 个答案:

答案 0 :(得分:1)

受保护的方法只能由封装在类或子类本身中的方法调用,而不能直接从类/子类的实例中调用。如果您想从实例中调用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

答案 1 :(得分:0)

除了动态调度外,您无法从外部访问受保护的方法或私有方法来获取红宝石。我的意思是laptop.eat将引发异常,但是laptop.send(:eat)将使该方法运行。这是动态调度。

答案 2 :(得分:0)

  • 方法和常量的可见性或访问权限可以通过 公共,私有或受保护的方法。
  • 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)