Ruby 面向对象
在 Ruby 中,面向对象编程(OOP) 是其核心设计哲学之一。Ruby 是纯面向对象的语言,一切皆对象(包括数字、字符串等基本类型)。以下是对 Ruby 面向对象编程的中文讲解,涵盖类、对象、继承、模块、方法等关键概念,力求简洁清晰。
1. 基本概念
- 类(Class):定义对象的蓝图,包含属性(实例变量)和行为(方法)。
- 对象(Object):类的实例,通过调用类的
new
方法创建。 - 一切皆对象:在 Ruby 中,数字(如
1
)、字符串(如"hello"
)等都是对象,可以调用方法。
puts 1.class # 输出:Integer
puts "hello".class # 输出:String
2. 定义类与创建对象
定义类
使用 class
关键字定义类,类名通常首字母大写(CamelCase)。
class Person
def initialize(name, age) # 构造函数
@name = name # 实例变量
@age = age
end
def introduce
"Hi, I'm #{@name}, #{@age} years old."
end
end
创建对象
通过 new
方法创建类的实例。
person = Person.new("Alice", 25)
puts person.introduce # 输出:Hi, I'm Alice, 25 years old.
说明:
initialize
是构造函数,创建对象时自动调用。@name
和@age
是实例变量,存储对象的状态。
3. 属性访问
Ruby 使用 attr_accessor
, attr_reader
, attr_writer
定义属性访问方法。
- attr_accessor:生成 getter 和 setter。
class Person
attr_accessor :name, :age # 自动生成 name, name=, age, age= 方法
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Bob", 30)
puts person.name # 输出:Bob
person.age = 31
puts person.age # 输出:31
- attr_reader:仅生成 getter。
- attr_writer:仅生成 setter。
手动定义 getter/setter:
class Person
def name
@name
end
def name=(value)
@name = value
end
end
4. 类方法与实例方法
- 实例方法:作用于对象,由实例调用。
class Person
def say_hello
"Hello!"
end
end
person = Person.new
puts person.say_hello # 输出:Hello!
- 类方法:作用于类本身,使用
self.
或class << self
定义。
class Person
def self.info
"This is the Person class."
end
end
puts Person.info # 输出:This is the Person class.
5. 继承
Ruby 支持单一继承,类通过 <
继承父类。
class Student < Person
def initialize(name, age, grade)
super(name, age) # 调用父类的 initialize
@grade = grade
end
def introduce
super + " I'm in grade #{@grade}." # 重写父类方法
end
end
student = Student.new("Charlie", 15, 10)
puts student.introduce # 输出:Hi, I'm Charlie, 15 years old. I'm in grade 10.
说明:
super
调用父类的同名方法。- Ruby 不支持多重继承,但通过模块(Mixin)实现类似功能。
6. 模块与 Mixin
模块(Module
)用于代码复用和命名空间管理,不能实例化,但可以通过 include
或 extend
混入类。
Mixin 示例
module Greetable
def greet
"Hello from #{self.class}!"
end
end
class Person
include Greetable
end
class Robot
include Greetable
end
person = Person.new
robot = Robot.new
puts person.greet # 输出:Hello from Person!
puts robot.greet # 输出:Hello from Robot!
说明:
include
:模块方法成为类的实例方法。extend
:模块方法成为类的类方法。
7. 访问控制
Ruby 提供三种访问控制修饰符:
public
:默认,方法可被任何人调用。private
:方法只能在类内部或实例方法中调用。protected
:方法可被同一类的实例或子类实例调用。
class Person
def initialize(name)
@name = name
end
def public_method
puts "This is public."
private_method
end
private
def private_method
puts "This is private."
end
protected
def protected_method
puts "This is protected."
end
end
person = Person.new("Alice")
person.public_method # 输出:This is public. This is private.
# person.private_method # 错误:private method
# person.protected_method # 错误:protected method
说明:
private
方法不能通过实例显式调用。protected
方法允许同一类实例之间调用。
8. 类变量与实例变量
- 实例变量(
@var
):每个对象独有。
class Person
def initialize(name)
@name = name
end
end
- 类变量(
@@var
):类及其子类共享。
class Person
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
end
Person.new
Person.new
puts Person.count # 输出:2
9. 单例方法
单例方法是为特定对象定义的方法,不影响其他对象。
person = Person.new("Alice")
def person.unique_method
puts "I'm unique!"
end
person.unique_method # 输出:I'm unique!
# Person.new.unique_method # 错误:undefined method
10. 动态特性
Ruby 是动态语言,支持运行时修改类和对象。
- 重定义方法:
class Person
def say
"Original"
end
end
class Person
def say
"Redefined"
end
end
puts Person.new.say # 输出:Redefined
- method_missing:处理未定义方法。
class Person
def method_missing(name, *args)
puts "未找到方法:#{name}"
end
end
Person.new.unknown # 输出:未找到方法:unknown
11. 注意事项
- 一切皆对象:Ruby 中没有基本类型,所有值都是对象。
- 单一继承:Ruby 只支持单一继承,使用模块实现多重继承效果。
- 动态性:支持运行时修改类和对象,但需谨慎,避免代码不可预测。
- 命名规范:
- 类/模块:CamelCase(如
MyClass
)。 - 方法:snake_case(如
my_method
)。 - 性能:大量动态操作(如
method_missing
)可能影响性能。 - 访问控制:明确使用
private
和protected
提高代码安全性。
12. 示例:综合应用
module Loggable
def log(message)
puts "[LOG] #{message}"
end
end
class Person
include Loggable
attr_accessor :name
@@count = 0
def initialize(name)
@name = name
@@count += 1
log("Created person: #{name}")
end
def self.count
@@count
end
end
class Student < Person
def initialize(name, grade)
super(name)
@grade = grade
end
end
# 测试
person = Person.new("Alice")
student = Student.new("Bob", 10)
puts person.name # 输出:Alice
puts Person.count # 输出:2
person.log("Test") # 输出:[LOG] Test
13. 总结
Ruby 的面向对象编程以类、对象和模块为核心,强调一切皆对象和动态性。类通过 initialize
定义对象,模块通过 Mixin 实现代码复用,继承和访问控制增强了代码组织。Ruby 的动态特性(如 method_missing
)提供了灵活性,但需注意性能和可维护性。结合模块和异常处理,Ruby 的 OOP 适合快速开发和复杂系统设计。
如果你有具体问题或需要更详细的示例,请告诉我!