可见性¶
方法默认情况下是公开的:编译器将始终允许您调用它们。由于这个原因,没有 public
关键字。
方法可以标记为 private
或 protected
。
私有方法¶
只能在没有接收者的情况下调用 private
方法,也就是说,在点号之前没有东西。唯一的例外是 self
作为接收者。
class Person
private def say(message)
puts message
end
def say_hello
say "hello" # OK, no receiver
self.say "hello" # OK, self is a receiver, but it's allowed.
other = Person.new
other.say "hello" # Error, other is a receiver
end
end
请注意,子类可以访问 private
方法。
class Employee < Person
def say_bye
say "bye" # OK
end
end
私有类型¶
私有类型只能在其定义的命名空间内引用,而不能被完全限定。
class Foo
private class Bar
end
Bar # OK
Foo::Bar # Error
end
Foo::Bar # Error
private
可与 class
、module
、lib
、enum
、alias
和常量一起使用。
class Foo
private ONE = 1
ONE # => 1
end
Foo::ONE # Error
受保护的方法¶
protected
方法只能在以下情况下调用:
- 与当前类型相同的类型的实例
- 与当前类型在同一个命名空间(类、结构体、模块等)中的实例
# Example of 1
class Person
protected def say(message)
puts message
end
def say_hello
say "hello" # OK, implicit self is a Person
self.say "hello" # OK, self is a Person
other = Person.new "Other"
other.say "hello" # OK, other is a Person
end
end
class Animal
def make_a_person_talk
person = Person.new
person.say "hello" # Error: person is a Person but current type is an Animal
end
end
one_more = Person.new "One more"
one_more.say "hello" # Error: one_more is a Person but current type is the Program
# Example of 2
module Namespace
class Foo
protected def foo
puts "Hello"
end
end
class Bar
def bar
# Works, because Foo and Bar are under Namespace
Foo.new.foo
end
end
end
Namespace::Bar.new.bar
protected
方法只能从其类或其子类的范围调用。这包括类范围以及定义 protected
方法的相同类型(与 protected
方法定义的类型相同)的类方法和实例方法的正文,以及所有包含或继承该类型以及该命名空间中的所有类型。
class Parent
protected def self.protected_method
end
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
end
def self.class_method
Parent.protected_method # OK
end
end
class Child < Parent
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
end
def self.class_method
Parent.protected_method # OK
end
end
class Parent::Sub
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
end
def self.class_method
Parent.protected_method # OK
end
end
私有顶级方法¶
private
顶级方法只在当前文件中可见。
one.cr
private def greet
puts "Hello"
end
greet # => "Hello"
two.cr
require "./one"
greet # undefined local variable or method 'greet'
这使您可以定义只在该文件中已知的辅助方法。
私有顶级类型¶
private
顶级类型只在当前文件中可见。
one.cr
private class Greeter
def self.greet
"Hello"
end
end
Greeter.greet # => "Hello"
two.cr
require "./one"
Greeter.greet # undefined constant 'Greeter'