📜  红宝石 |访问控制

📅  最后修改于: 2022-05-13 01:55:14.829000             🧑  作者: Mango

红宝石 |访问控制

访问控制是面向对象编程语言中非常重要的一部分,用于限制方法和成员字段的可见性,以保护数据不被意外修改。在访问控制方面,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

错误:

受保护的方法

受保护的方法只能被定义的类及其子类的对象调用。这些方法的访问被限制在定义的类或其子类之间。您不能访问已定义类或其子类之外的受保护方法。受保护方法的使用是有限的。受保护的方法是使用受保护的关键字定义的。

例子:

# 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

错误:

笔记:

  • 用户可以在同一类的公共方法中调用私有方法和受保护方法。

    例子:

    # 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
    

    错误:

  • 受保护方法和私有方法之间的主要区别在于,受保护方法可以通过使用显式接收器从类内部访问,而私有方法则不能。

    例子:

    # 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