Ruby 类
Ruby 类和对象:OOP 的蓝图
Section titled “Ruby 类和对象:OOP 的蓝图”Ruby 是一种纯粹的面向对象编程(Object-Oriented Programming, OOP)语言。核心 OOP 原则包括:
- **数据封装(Data Encapsulation):**将数据(attributes,属性)和操作数据的方法(methods)捆绑在单个单元(object,对象)中。对内部状态的访问受到控制。
- **数据抽象(Data Abstraction):**隐藏复杂的实现细节,只暴露对象的必要特性。
- **多态(Polymorphism):**不同类的对象能够以各自类特定的方式响应同一消息(方法调用)的能力。
- **继承(Inheritance):**允许一个新类(subclass,子类)继承现有类(superclass,超类)的属性和方法,促进代码复用并建立类之间的关系。
在 Ruby 中,一切皆对象。一个 class(类)是创建 object(对象)的蓝图。一个 object(对象)是 class 的一个实例(instance)。例如,如果 String 是一个类,那么 "hello" 就是一个对象(一个 String 的实例)。
在 Ruby 中定义类:
Section titled “在 Ruby 中定义类:”类定义以 class 关键字开始,后跟类名(按照约定,类名必须以大写字母开头,例如 CamelCase),以 end 关键字结束。
class Vehicle # Class content (attributes and methods) goes hereendRuby 类中的变量:
Section titled “Ruby 类中的变量:”Ruby 在类的上下文中支持几种类型的变量:
- **局部变量(Local Variables):**定义在方法内部。它们的作用域(scope)仅限于该方法。名称以小写字母或
_开头(例如my_var)。 - **实例变量(Instance Variables):**属于类的特定实例(对象)。它们保存对象的状态。名称以
@符号开头(例如@color)。每个对象可以为其实例变量拥有不同的值。 - **类变量(Class Variables):**在类的所有实例之间共享,也可以由类本身访问。名称以
@@开头(例如@@count)。对类变量的修改对所有实例可见。使用时需谨慎,尤其是在继承场景下,它们的行为有时可能令人意外。 - **全局变量(Global Variables):**程序中任何地方都可以访问。名称以
$符号开头(例如$debug_mode)。全局变量应尽量少用,因为它们会使代码难以维护和调试。
示例:一个简单的 Car 类
Section titled “示例:一个简单的 Car 类”#!/usr/bin/ruby
class Car # Class variable to keep track of the number of cars created @@number_of_cars = 0
# Shortcut for creating getter and setter methods for @color and @make # attr_reader :color # Only getter # attr_writer :color # Only setter attr_accessor :color, :make # Both getter and setter
# The initialize method is a special constructor called when Car.new is invoked def initialize(make, color) @make = make # Instance variable @color = color # Instance variable @@number_of_cars += 1 puts "Initialized a #{@color} #{@make}." end
# Instance method def start_engine puts "The #{@make}'s engine roars to life!" end
# Class method (note the 'self.') def self.total_cars_created "Total cars created: #{@@number_of_cars}" endend
# Creating Objects (Instances of the Car class)my_car = Car.new("Toyota", "Red")her_car = Car.new("Honda", "Blue")
# Accessing instance variables (via attr_accessor)puts "My car is a #{my_car.color} #{my_car.make}."my_car.color = "Silver" # Using the setterputs "My car is now #{my_car.color}."
# Calling instance methodsmy_car.start_engineher_car.start_engine
# Calling a class methodputs Car.total_cars_created这将产生类似于以下的输出:
Initialized a Red Toyota.Initialized a Blue Honda.My car is a Red Toyota.My car is now Silver.The Toyota's engine roars to life!The Honda's engine roars to life!Total cars created: 2initialize 方法(构造方法):
Section titled “initialize 方法(构造方法):”initialize 方法是 Ruby 类中一个特殊的私有方法。当你使用 ClassName.new 创建新对象时,它会自动被调用。它主要用于通过为实例变量赋值来设置对象的初始状态。
实例方法(Instance Methods)和类方法(Class Methods):
Section titled “实例方法(Instance Methods)和类方法(Class Methods):”**实例方法(Instance methods)**作用于类的实例(即对象)。它们可以访问对象的实例变量(例如 Car 示例中的 start_engine)。
**类方法(Class methods)**在类本身上调用,而不是在实例上调用。它们通过在方法名称前加上 self. 来定义(例如 self.total_cars_created)。它们无法访问实例的变量,但可以访问类变量。
属性访问器(Attribute Accessors):attr_reader, attr_writer, attr_accessor:
Section titled “属性访问器(Attribute Accessors):attr_reader, attr_writer, attr_accessor:”Ruby 提供了方便的快捷方式来创建常用的实例变量的 Getter 和 Setter 方法:
attr_reader :variable_name创建一个 Getter 方法(例如def variable_name; @variable_name; end)。attr_writer :variable_name创建一个 Setter 方法(例如def variable_name=(value); @variable_name = value; end)。attr_accessor :variable_name创建一个 Getter 和一个 Setter 方法。
使用这些访问器可以使代码更简洁和符合 Ruby 习惯。
方法可见性(Method Visibility):public, private, protected
Section titled “方法可见性(Method Visibility):public, private, protected”Ruby 使用可见性关键字控制方法的访问:
public: 方法可以在任何地方访问。这是默认的可见性。private: 方法只能由同一类实例内部的其他方法调用(隐式调用,即不带self.作为接收者,Setter 方法self.foo =除外)。子类或直接在对象上都无法访问它们。protected: 方法可以由定义类及其子类的实例调用。它们可以带有显式接收者调用(例如other_object.protected_method),只要other_object是调用者类的实例或其子类。
class BankAccount attr_reader :balance
def initialize(initial_deposit) @balance = initial_deposit end
def deposit(amount) @balance += amount log_transaction("Deposit: #{amount}") end
def withdraw(amount) if can_withdraw?(amount) @balance -= amount log_transaction("Withdrawal: #{amount}") else puts "Insufficient funds!" end end
# Protected: Accessible by BankAccount and its subclasses protected def can_withdraw?(amount) @balance >= amount end
# Private: Only accessible within this BankAccount instance private def log_transaction(message) puts "[LOG] #{Time.now}: #{message}, New Balance: #{@balance}" endend
account = BankAccount.new(100)account.deposit(50)account.withdraw(30)# account.log_transaction("test") # This would raise NoMethodError (private)# account.can_withdraw?(10) # This would raise NoMethodError (protected, if called from outside directly)实际应用:
类和对象是大多数 Ruby 应用程序的基石。它们用于建模现实世界中的实体(如用户、产品、订单)、抽象概念(如数据库连接或文件解析器),以及组织代码以实现复用和可维护性。Ruby on Rails 等框架严重依赖基于类的结构(Model、View、Controller)。