在面向对象编程中,继承允许一个类重用另一个类的代码。
例如,如果你有一个 Animal 类,那么 Dog 类可以继承它的行为(因为狗是动物的一种)。
class Animal
def speak
puts "I'm an animal"
end
end
# Create Dog class that inherits from Animal
class Dog < Animal
end
Dog.new.speak
# Output: I'm an animal
这意味着 Dog 类会自动从 Animal 类中获得 speak 方法。
Ruby 继承语法
在 Ruby 中,继承使用 < 符号来实现。
class ChildClass < ParentClass
end
这告诉 Ruby,一个类(子类)继承自另一个类(父类)。例如,
class Dog < Animal
end
这里,
Dog是子类。Animal是父类(或超类)。- 这意味着
Dog继承了父类所有方法的访问权限,以及那些方法初始化的实例变量。
访问父类方法和实例变量
假设 Animal 类有一个实例变量 @name(通过构造函数设置)和一个 speak 方法,该方法使用该变量打印一条消息。
我们来看看 Dog 子类如何继承这个实例变量和方法。
class Animal
def initialize(name)
@name = name
end
def speak
puts "#{@name} makes a sound"
end
end
class Dog < Animal
end
dog = Dog.new("Tommy")
dog.speak
输出
Tommy makes a sound
在这个例子中,Dog 类继承自 Animal,但没有添加自己的任何新代码。
然而,当我们创建一个 Dog 对象并调用 speak 方法时,它会在 speak 执行之前自动使用 initialize 方法来设置 @name。
正如你所见,这两个方法都定义在父类中。
这表明 Dog 完全继承了 Animal 的行为和数据,即使没有重新定义任何内容。
添加子类特有的行为
继承不仅允许子类重用其父类的代码,还允许子类添加自己的新行为。
让我们在之前的例子基础上,为 Dog 类添加一个 wag_tail 方法。
class Animal
def initialize(name)
@name = name
end
def speak
puts "#{@name} makes a sound"
end
end
class Dog < Animal
def wag_tail
puts "#{@name} is wagging its tail"
end
end
dog = Dog.new("Tommy")
dog.speak
dog.wag_tail
输出
Tommy makes a sound Tommy is wagging its tail
在这里,Dog 类仍然从 Animal 类继承 initialize 和 speak 方法。但它也定义了自己的方法 wag_tail。
重写父类方法
有时,你可能希望子类改变继承方法的行为方式。
在 Ruby 中,你可以通过在子类中重新定义该方法来实现,这被称为 **方法重写**。
让我们以之前讨论的 Animal 类为例,并在其子类中重写其中一个方法。
class Animal
def initialize(name)
@name = name
end
def speak
puts "#{@name} makes a sound"
end
end
class Dog < Animal
# Override the speak method
def speak
puts "#{@name} says Woof!"
end
end
dog = Dog.new("Tommy")
dog.speak
# Output: Tommy says Woof!
在这里,Dog 类重写了 Animal 中的 speak 方法。
Dog 中重写的方法将通用消息替换为更具体的消息:“Tommy says Woof!”。
常见问题
是的,可以。在 Ruby 中,你可以在子类方法中使用 super 关键字来调用父类中的原始版本。
这允许你扩展父类的行为,而不是完全替换它。例如,
class Animal
def initialize(name)
@name = name
end
def speak
puts "#{@name} makes a sound"
end
end
class Dog < Animal
def speak
super
puts "#{@name} barks happily!"
end
end
dog = Dog.new("Tommy")
dog.speak
# Output:
# Tommy makes a sound
# Tommy barks happily!
使用 super 关键字,你可以建立在父类已有的功能之上。
Ruby 的单一继承模型
Ruby 只支持单一继承,这意味着一个类一次只能继承自一个父类。
允许:从一个类继承
class A
end
class B < A
end
在这里,B 类继承自 A 类。这在 Ruby 中是允许的,并且可以完美运行。
不允许:从多个类继承
class A
end
class B
end
# This will raise an error in Ruby
class C < A, B
end
Ruby 不支持多重继承,你不能直接从多个类继承。