Невозможно получить доступ к защищенному методу в Ruby - PullRequest
0 голосов
/ 17 февраля 2019

Я изучал концепцию инкапсуляции в ruby.

Ниже приведен пример кода, ноутбук наследуется от машины, я сделал есть защищенный метод (класс машины), но не могу получить доступ через экземпляр ноутбука.

Кроме того, я не могу получить доступ к защищенному методу ноутбука под названием 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 голосов
/ 17 февраля 2019

Вы не можете получить доступ к защищенным или закрытым методам извне для ruby, за исключением динамической диспетчеризации.Я имею в виду laptop.eat вызовет исключение, однако, laptop.send(:eat) заставит запустить метод.Это динамическая диспетчеризация.

0 голосов
/ 18 февраля 2019
  • Видимость или доступ к методам и константам можно установить с помощью методов public, private или protected.
  • 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)
    
0 голосов
/ 17 февраля 2019

Защищенные методы могут вызываться только методами, инкапсулированными в самом классе или подклассе, а не непосредственно из экземпляра класса / подкласса.Если вы хотите, чтобы метод 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
...