Я изучал концепцию инкапсуляции в ruby.
Ниже приведен пример кода, ноутбук наследуется от машины, я сделал защищенный метод (класс машины), но не могу получить доступ через экземпляр ноутбука.
Кроме того, я не могу получить доступ к защищенному методу ноутбука, называемому описанием.
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>'

Защищенные методы могут вызываться только методами, инкапсулированными в самом классе или подклассе, а не напрямую из экземпляра класса/подкласса. Если вы хотите, чтобы метод 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
Также см.: en.wikibooks.org/wiki/Ruby_Programming/Синтаксис/Классы
утверждение, что экземпляры класса могут использоваться, вводит в заблуждение и в значительной степени не соответствует действительности. Он может использоваться классом и подклассами ВНУТРЕННИ. Разница между private и protected заключается в том, что частные методы не могут использоваться подклассами.
да. Но вы не используете его в экземпляре класса, в котором он был определен, или в производном классе. Вы используете его на верхнем уровне, то есть в Object.
@JörgWMittag, см. Метод описания класса Laptop, также в ruby создание экземпляра не означает создание объекта?
да. description защищен. Это означает, что вы можете вызывать его в Laptop и во всех его подклассах. Но вы называете это Object, который не является подклассом Laptop.
Вы называете это on экземпляром Laptop, а не in экземпляром Laptop .. это лучше объясняет?
Вы не можете получить доступ к защищенным или частным методам извне для ruby, кроме динамической диспетчеризации. Я имею в виду, что laptop.eat вызовет исключение, однако laptop.send(:eat) заставит запустить метод. Это динамическая диспетчеризация.
Что ты имеешь в виду?
Это объясняется в документации, в спецификации языка и в самой книге по Ruby, учебнике по Ruby и курсе по 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)
Метод, помеченный как защищенный, означает, что его могут использовать только экземпляры класса, в котором он был определен, или производные классы. Источник: Изучение Ruby Майкла Фицджеральда.