Ruby语言中,访问修饰符有三个:public、protected和private。
Ruby指定方法访问权限的方式有两种,一种是在定义方法之前声明方法的访问权限,另一种是在方法定义后指定访问权限。
代码段1:
- class Sup
- private
- def method1
- puts "method1"
- end
- protected
- def method2
- puts "method2"
- end
- public
- def method3
- puts "method3"
- end
- end
class Sup
private
def method1
puts "method1"
end
protected
def method2
puts "method2"
end
public
def method3
puts "method3"
end
end
代码段2:
- class Sup
- def method1
- puts "method1"
- end
- def method2
- puts "method2"
- end
- def method3
- puts "method3"
- end
- private :method1
- protected :method2
- public :method3
- end
class Sup
def method1
puts "method1"
end
def method2
puts "method2"
end
def method3
puts "method3"
end
private :method1
protected :method2
public :method3
end
代码段1中,访问修饰符不能与方法名写在同一行,比如这样写,运行时就会报错:
- private def method1
private def method1
在Ruby中,换行就代表一句代码的结束,封号可以省略,也就是说这里的private已经是一句完整的代码了,如果非得放在同一行,这样写也是没错的,但没什么意义:
- private; def method1
private; def method1
Ruby中,方法的访问权限默认是public的(initialize除外,它默认是private的)。
代码段1中的声明方法,一个访问修饰符修饰之后的所有方法,直到下一个访问修饰符出现,如:
代码段3:
- class Sup
- private
- def method1
- puts "method1"
- end
- def method4
- puts "method4"
- end
- protected
- def method2
- puts "method2"
- end
- public
- def method3
- puts "method3"
- end
- end
class Sup
private
def method1
puts "method1"
end
def method4
puts "method4"
end
protected
def method2
puts "method2"
end
public
def method3
puts "method3"
end
end
这里在method1之后添加了一个method4,这个method4也是private的。但在代码段2中,如果往method1之后添加一个method4,这个method4仍然是public(默认)的。
在Ruby中:
protected(保护)方法只能被定义了该方法的类或其子类的对象所调用。整个家族均可访问。
private(私有)方法不能被明确的接收者调用,其接收者只能是self。这意味着私有方法只能在当前对象的上下文中被调用:你不能调用另一个对象的私有方法。
Ruby中:
代码段4:
- class Sup
- private
- def method1
- puts "method1"
- end
- end
- class Sub < Sup
- def method_1
- method1 #这样的代码是合法的
- end
- end
class Sup
private
def method1
puts "method1"
end
end
class Sub < Sup
def method_1
method1 #这样的代码是合法的
end
end
这样的代码是合法的,但在Java中:
代码段5:
- class Sup{
- private void method1(){
- System.out.println("method1");
- }
- }
- class Sub extends Sup{
- public void method_1(){
- method1();
- super.method1();//这2种调用方式都是不合法的,子类不继承父类的private方法,也不能通过super关键字调用父类的private方法。
- }
- }
class Sup{
private void method1(){
System.out.println("method1");
}
}
class Sub extends Sup{
public void method_1(){
method1();
super.method1();//这2种调用方式都是不合法的,子类不继承父类的private方法,也不能通过super关键字调用父类的private方法。
}
}
这2种调用方式都是不合法的,子类不继承父类的private方法,也不能通过super关键字调用父类的private方法。
Ruby中:
代码段6:
- class Sup
- def method2
- puts "method2"
- end
- protected :method2
- end
- class Sub < Sup
- def sup_method2
- sup = Sup.new
- sup.method2 #这样的代码是合法的
- end
- end
class Sup
def method2
puts "method2"
end
protected :method2
end
class Sub < Sup
def sup_method2
sup = Sup.new
sup.method2 #这样的代码是合法的
end
end
这样的代码是合法的,但在Java中:
代码段7:
- class Sup{
- protected void method2(){
- System.out.println("method1");
- }
- }
- class Sub extends Sup{
- public void sup_method2(){
- Sup sup = new Sup();
- sup.method2();//这样的代码只有当子类和父类在同一个包(package)下的时候才合法
- }
- }
class Sup{
protected void method2(){
System.out.println("method1");
}
}
class Sub extends Sup{
public void sup_method2(){
Sup sup = new Sup();
sup.method2();//这样的代码只有当子类和父类在同一个包(package)下的时候才合法
}
}
这样的代码只有当子类和父类在同一个包(package)下的时候才合法。
Ruby中,private跟protected的区别在哪呢?把代码段6中,method2的访问权限改成private再运行,就报错了。也就是前面说的“private(私有)方法不能被明确的接收者调用,其接收者只能是self。”。
因此private和protected的在ruby当前和Java的定义有很大的区别:
1、在不同对象实例当中的作用域不同
Java当中,不管private还是protected的方法,都可以被同一个类别的其他对象实例调用;
Ruby当中,private方法不能被同一个类别的其他对象实例调用;
2、在类继承关系当中的作用域不同
ruby当中,不管private还是protected方法,都可以被子类继承;
Java当中,private方法不能被子类继承;
这种方法调用的差异,也许来自于不同的面向对象理念:Java的面向对象来自C++,强调类继承关系,所以方法调用限定类继承的层次结构当中的作 用域,却不强调对象实例作用域;而ruby的面向对象来自smalltalk,即使是类别也是对象,因此方法调用作用域都是针对对象实例调用来设置的。