红宝石 |访问控制
访问控制是面向对象编程语言中非常重要的一部分,用于限制方法和成员字段的可见性,以保护数据不被意外修改。在访问控制方面,Ruby 不同于所有其他面向对象的编程语言。
关于 Ruby 访问控制的要点:
- 类变量和实例的可见性始终是私有的。
- 访问控制仅适用于方法。
- 我们不能对实例和类变量应用任何访问控制。
- Ruby 中的私有方法也可以像公共和受保护方法一样被继承。
在 Ruby 中,访问控制在两个条件下起作用:
- 首先,从哪里调用方法,即在类定义的内部或外部。
- 其次,是否包含self关键字。基本上,self-keyword 用于指向当前收件人。
在 Ruby 中,继承没有必要参与访问控制,就像在 C++ 中,访问控制在继承中使用。访问控制分为三种类型,如下图所示:
公共方法
公共方法是任何人都可以调用的方法。正如我们所知,访问控制仅适用于方法,因此默认情况下所有方法都是 public 。但是,我们仍然可以使用public关键字显式定义公共方法。公共方法通常在类外调用。
例子:
# Ruby program to demonstrate
# the public access control
#!/usr/bin/ruby
# taking a class
class GeeksforGeeks
# public method without using
# public keyword
def geeks_1
puts "public method geeks_1 is called"
end
# using public keyword
public
def geeks_2
puts "public method geeks_2 is called"
end
def geeks_3
puts "public method geeks_3 is called"
# calling geeks_1 method
geeks_1
# calling geeks_1 method using
# self-keyword
self.geeks_1
end
end
# creating the object of
# class GeeksforGeeks
obj = GeeksforGeeks.new
# calling method geeks_1
obj.geeks_1
# calling method geeks_2
obj.geeks_2
# calling method geeks3
obj.geeks_3
输出:
public method geeks_1 is called
public method geeks_2 is called
public method geeks_3 is called
public method geeks_1 is called
public method geeks_1 is called
私有方法
私有方法是那些在类外部无法访问的方法,或者换句话说,私有方法只能在类定义内部调用。类的方法可以访问私有成员。在私有方法中,我们不使用 self 关键字。默认情况下,初始化方法将是私有方法。用户不能将初始化方法设为公共方法。私有方法是使用private关键字定义的。
注意:众所周知,私有方法的可见性受到严格限制,只有定义的类成员才能访问这些方法,但它们可以被子类继承。子类可以访问它们并且可以覆盖它们。
例子:
# Ruby program to demonstrate
# the private access control
#!/usr/bin/ruby
# creating class
class GeeksforGeeks
# using initialize method
# it can't be private
def initialize
puts "This is the initialize Method"
end
# public method
def geeks_1
puts "Public geeks_1 Method"
end
# using the private keyword to
# declare a private method
private
def geeks_2
puts "This is Private Method"
end
end
# creating the object of
# the class GeeksforGeeks
obj = GeeksforGeeks.new
# calling method geeks_1
# (geeks1 method is public method)
obj.geeks_1
# calling private method will give the error
obj.geeks_2
错误:
source_file.rb:41:in ` This is the initialize Method
Did you mean? geeks_1
Public geeks_1 Method
受保护的方法
受保护的方法只能被定义的类及其子类的对象调用。这些方法的访问被限制在定义的类或其子类之间。您不能访问已定义类或其子类之外的受保护方法。受保护方法的使用是有限的。受保护的方法是使用受保护的关键字定义的。
例子:
# Ruby program to demonstrate
# the protected access control
#!/usr/bin/ruby
class GeeksforGeeks
# using initialize method
def initialize
# calling geeks_2 method
geeks_2
# calling geeks_2 method
# using self-keyword
self.geeks_2
end
# public method
def geeks_1
puts " geeks_1 method is called"
end
# defining the protected method using
# protected keyword
protected
def geeks_2
puts " geeks_2 method is called"
end
end
# creating the object of class GeeksforGeeks
obj = GeeksforGeeks.new
# calling method
obj.geeks_1
# if you will try to call protected method
# using the object of class then it will
# give error
obj.geeks_2
错误:
source_file.rb:45:in ` geeks_2 method is called
Did you mean? geeks_1
geeks_2 method is called
geeks_1 method is called
笔记:
- 用户可以在同一类的公共方法中调用私有方法和受保护方法。
例子:
# Ruby program to demonstrate the calling # of private and protected method in the # public method class Geeks # public method def method_1 p "Public Method of class Geeks" # calling protected and private method # inside the public method method_2 method_3 end # defining the protected method protected def method_2 p "Protected Method of class Geeks" end # defining the private method private def method_3 p "Private Method of class Geeks" end end # creating an object of class Geeks obj = Geeks.new # calling the public method of class Geeks obj.method_1
输出:
"Public Method of class Geeks" "Protected Method of class Geeks" "Private Method of class Geeks"
- 一般来说,私有方法不能在面向对象的编程语言中被继承。但在 Ruby 中,私有方法也可以像受保护和公共方法一样被继承。
例子:
# Ruby program to demonstrate that private # method can also be inherited class Geeks # public method def method_1 p "Public Method of class Geeks" end # defining the protected method protected def method_2 p "Protected Method of class Geeks" end # defining the private method private def method_3 p "Private Method of class Geeks" end end # Sudo class inheriting Geeks class class Sudo < Geeks # public method of Sudo class def method_4 p "Public Method of Sudo Class" # calling all three methods # of Geeks class method_1 method_2 method_3 end end # creating an object of class Sudo obj_sudo = Sudo.new # calling the public method # of class Sudo which will # automatically call the private # and protected method of Geeks class obj_sudo.method_4
输出:
"Public Method of Sudo Class" "Public Method of class Geeks" "Protected Method of class Geeks" "Private Method of class Geeks"
- 公共方法可以在定义它们的类之外访问。但是用户无法访问定义它们的类之外的私有和受保护方法。
例子:
# Ruby program to demonstrate that private # and protected method can't be accessed # outside the class even after inheritance class Geeks # public method def method_1 p "Public Method of class Geeks" end # defining the protected method protected def method_2 p "Protected Method of class Geeks" end # defining the private method private def method_3 p "Private Method of class Geeks" end end # Sudo class inheriting Geeks class class Sudo < Geeks # public method of Sudo class def method_4 p "Public Method of Sudo Class" end end # creating an object of class Sudo obj_sudo = Sudo.new # calling the public method # of class Sudo and Geeks obj_sudo.method_4 obj_sudo.method_1 # if you will try to call the protected # and private method using the object # of class Sudo, then it will give error obj_sudo.method_2 obj_sudo.method_3
错误:
source_file.rb:54:in `
‘: protected method `method_2’ called for #<0x000000016e40a0> (NoMethodError)
Did you mean? method
method_1
method_4
methods“Public Method of Sudo Class”
0x000000016e40a0>
“Public Method of class Geeks” - 受保护方法和私有方法之间的主要区别在于,受保护方法可以通过使用显式接收器从类内部访问,而私有方法则不能。
例子:
# Ruby program to demonstrate that private # and protected method can't be accessed # outside the class even after inheritance class Geeks # public method def method_1 p "Public Method of class Geeks" end # defining the protected method protected def method_2 p "Protected Method of class Geeks" end # defining the private method private def method_3 p "Private Method of class Geeks" end end # Sudo class inheriting Geeks class class Sudo < Geeks # public method of Sudo class def method_4 p "Public Method of Sudo Class" # calling the public method # of Geeks class method_1 # creating object of class Sudo # inside the public method of # class Sudo obj_inside_sudo = Sudo.new # calling the protected # method of class Geeks obj_inside_sudo.method_2 # calling the private # method of class Geeks # using an explicit receiver obj_inside_sudo.method_3 rescue p "You can't Access!" end end # creating an object of class Sudo obj_sudo = Sudo.new # calling the public method # of class Sudo obj_sudo.method_4
输出:
"Public Method of Sudo Class" "Public Method of class Geeks" "Protected Method of class Geeks" "You can't Access!"
- 要在单个类中定义多个受保护和私有方法,可以使用以下语法:
class class_name # this method is public def public_method end public :method_1 protected :method_2, :method_3 private :method_4, :method_5 end