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

Unable to access protected method in Ruby

我在 ruby 学习封装的概念。

下面是示例代码,Laptop继承自Machine,我将eat设置为受保护的方法(Machineclass),但无法通过Laptop的实例访问。

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

受保护的方法只能由封装在 class 或 subclass 本身的方法调用,不能直接从 class/subclass 的实例调用。如果您希望从实例调用 eat 方法而不是将其设为 public 或从另一个 public 方法调用它:

[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

除动态调度外,您无法从外部为 ruby 访问受保护或私有方法。我的意思是 laptop.eat 会引发异常,但是,laptop.send(:eat) 会使 运行 成为方法。这就是动态调度。

  • 方法和常量的可见性或访问权限可以通过 方法 public、私有或受保护。
  • Ruby 不允许您访问或更改实例变量形式 在 class 之外。为了克服这个你必须使用访问器 方法
  • 私有方法只能在 class 中调用,不能从 class 本身的实例也不与 self 关键字一起使用

  • 受保护的方法只能被封装在class或subclass本身的方法调用,不能直接从class/subclass的实例中调用。

     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)