Ruby 类和对象
Ruby 类和对象中文讲解
Ruby 是一种纯粹的面向对象编程语言,一切皆对象,包括数字、字符串等基本数据类型。类(Class)和对象(Object)是 Ruby 面向对象编程的核心。本文将详细讲解 Ruby 中的类和对象,涵盖定义、实例化、继承、方法、模块以及中文处理相关内容,基于 Ruby 3.4.x(截至 2025 年 8 月的最新稳定版)。本文适合初学者,同时提供中文相关注意事项。
1. 类和对象基础
- 类(Class):类是对象的蓝图,定义了对象的属性(数据)和行为(方法)。
- 对象(Object):对象是类的实例,通过类创建,包含特定数据和行为。
- Ruby 的特性:每个对象都是某个类的实例,例如
"你好"
是String
类的对象,42
是Integer
类的对象。
示例:
# 检查对象所属类
puts "你好".class # 输出: String
puts 42.class # 输出: Integer
2. 定义类
使用 class
关键字定义类,类名通常以大写字母开头(遵循 Ruby 的命名规范)。
2.1 基本类定义
# encoding: UTF-8
class Person
def initialize(name, age) # 构造函数
@name = name # 实例变量
@age = age
end
def introduce # 实例方法
"我叫#{@name},#{@age}岁"
end
end
- 说明:
initialize
是构造函数,在创建对象时调用。@name
和@age
是实例变量,存储对象的状态。introduce
是实例方法,定义对象的行为。
2.2 创建对象
通过 new
方法实例化类:
# encoding: UTF-8
person = Person.new("小明", 20)
puts person.introduce # 输出: 我叫小明,20岁
3. 实例变量和方法
- 实例变量:以
@
开头,属于特定对象,作用域为整个对象。 - 实例方法:定义在类中,供对象调用。
示例:
# encoding: UTF-8
class Student
def initialize(name, grade)
@name = name
@grade = grade
end
def study
"#{@name} 正在学习,成绩:#{@grade}"
end
end
student = Student.new("小红", "A")
puts student.study # 输出: 小红 正在学习,成绩:A
3.1 访问器(Getter 和 Setter)
Ruby 提供便捷方式定义属性访问器:
- 使用
attr_reader
(只读)、attr_writer
(只写)、attr_accessor
(读写)。
# encoding: UTF-8
class Person
attr_accessor :name, :age # 自动生成 getter 和 setter
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("小明", 20)
puts person.name # 输出: 小明
person.age = 21 # 修改 age
puts person.age # 输出: 21
4. 类变量和类方法
- 类变量:以
@@
开头,共享于类及其所有实例。 - 类方法:使用
self.
或class << self
定义,属于类本身而非实例。
示例:
# encoding: UTF-8
class Person
@@count = 0 # 类变量
def initialize(name)
@name = name
@@count += 1
end
def self.total_count # 类方法
"总共创建了 #{@@count} 个 Person 对象"
end
end
p1 = Person.new("小明")
p2 = Person.new("小红")
puts Person.total_count # 输出: 总共创建了 2 个 Person 对象
5. 继承
Ruby 支持单继承,使用 <
指定父类,子类可以继承父类的属性和方法。
示例:
# encoding: UTF-8
class Person
def initialize(name)
@name = name
end
def introduce
"我叫#{@name}"
end
end
class Student < Person
def initialize(name, grade)
super(name) # 调用父类的 initialize
@grade = grade
end
def study
"#{@name} 在学习,成绩:#{@grade}"
end
end
student = Student.new("小红", "A")
puts student.introduce # 输出: 我叫小红
puts student.study # 输出: 小红 在学习,成绩:A
- 说明:
super
调用父类同名方法。- 子类可以扩展或重写父类方法。
6. 模块(Module)
模块用于组织代码或提供混入(Mixin)功能,不能直接实例化,但可被类包含。
6.1 定义模块
# encoding: UTF-8
module Greetable
def say_hello
"你好!"
end
end
6.2 混入模块
使用 include
将模块混入类:
# encoding: UTF-8
class Person
include Greetable
attr_accessor :name
def initialize(name)
@name = name
end
end
person = Person.new("小明")
puts person.say_hello # 输出: 你好!
puts person.name # 输出: 小明
6.3 模块作为命名空间
模块可用于避免命名冲突:
# encoding: UTF-8
module Chinese
class Person
def say
"你好,我是中文 Person"
end
end
end
module English
class Person
def say
"Hello, I am English Person"
end
end
end
zh = Chinese::Person.new
en = English::Person.new
puts zh.say # 输出: 你好,我是中文 Person
puts en.say # 输出: Hello, I am English Person
7. 中文处理相关内容
Ruby 对中文的支持依赖于正确的编码配置,以下是类和对象中处理中文的注意事项:
- 编码声明:
- 确保脚本以 UTF-8 保存并声明:
ruby # encoding: UTF-8
- Windows 用户若处理 GBK(旧系统),声明:
ruby # encoding: GBK
- 中文实例变量和方法:
# encoding: UTF-8
class Person
def initialize(姓名)
@姓名 = 姓名
end
def 介绍
"你好,我的名字是#{@姓名}"
end
end
person = Person.new("小明")
puts person.介绍 # 输出: 你好,我的名字是小明
- 注意:中文方法名合法但不推荐,建议使用英文以提高代码可读性。
- 中文字符串操作:
- 在类中处理中文字符串:
# encoding: UTF-8 class TextProcessor def initialize(text) @text = text end def count_chinese @text.scan(/\p{Han}/).length end end processor = TextProcessor.new("你好,世界!") puts processor.count_chinese # 输出: 4(你好世界)
- 文件操作与中文:
- 保存对象数据到文件:
# encoding: UTF-8 class Person attr_accessor :name def initialize(name) @name = name end def save_to_file File.write("person.txt", @name, encoding: "UTF-8") end end person = Person.new("小明") person.save_to_file
- 乱码问题:
- Windows CMD:默认 GBK 可能导致乱码,切换到 UTF-8:
bash chcp 65001
- 确保终端和文件编码一致,或使用 PowerShell/Windows Terminal。
- 检查对象字符串编码:
ruby puts person.name.encoding # 输出: UTF-8
8. 代码示例
- 完整类示例:
# encoding: UTF-8
class Person
@@count = 0
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
@@count += 1
end
def introduce
"我叫#{@name},#{@age}岁"
end
def self.total_count
"总共创建了 #{@@count} 个对象"
end
end
p1 = Person.new("小明", 20)
p2 = Person.new("小红", 18)
puts p1.introduce # 输出: 我叫小明,20岁
puts Person.total_count # 输出: 总共创建了 2 个对象
- 继承与模块:
# encoding: UTF-8
module Learnable
def learn
"学习中..."
end
end
class Person
def initialize(name)
@name = name
end
end
class Student < Person
include Learnable
def introduce
"我是学生#{@name}"
end
end
student = Student.new("小明")
puts student.introduce # 输出: 我是学生小明
puts student.learn # 输出: 学习中...
9. 常见问题与解决
- 中文乱码:
- 原因:脚本或终端编码不一致。
- 解决:
- 添加
# encoding: UTF-8
。 - Windows 用户运行:
bash chcp 65001 set RUBYOPT=-EUTF-8
- 使用 UTF-8 保存文件(无 BOM)。
- 添加
- 实例变量未初始化:
- 原因:访问未定义的实例变量返回
nil
。 - 解决:
ruby class Person def initialize @name ||= "默认姓名" # 设置默认值 end end
- 方法重写错误:
- 原因:子类意外覆盖父类方法。
- 解决:使用
super
调用父类方法。
10. 最佳实践
- 命名规范:类名使用驼峰式(
CamelCase
),方法和变量使用下划线(snake_case
)。 - 编码统一:始终使用 UTF-8,避免 GBK 除非必要。
- 模块化:使用模块组织代码,增强复用性。
- 访问控制:
- 使用
private
或protected
限制方法访问:ruby class Person private def secret "这是秘密" end end
11. 进阶建议
- 学习 Rails:Rails 广泛使用类和对象(如模型类):
class User < ApplicationRecord
validates :name, presence: true
end
- 调试工具:
- 使用
pry
检查对象:bash gem install pry
ruby require 'pry' person = Person.new("小明", 20) binding.pry # 检查 person.instance_variables
- 国际化(i18n):
- 在 Rails 中使用
i18n
gem 处理中文:yaml # config/locales/zh-CN.yml zh-CN: hello: "你好"
12. 社区资源
- Ruby 官方文档:ruby-doc.org
- Ruby China:ruby-china.org
- 《Programming Ruby》(Pickaxe Book)
通过以上讲解,你可以全面掌握 Ruby 的类和对象,并处理中文相关任务。如果需要深入某个主题(如继承、模块或 Rails 模型),请告诉我!