Ruby类继承

3

我已经做了很多有关在Ruby中将对象转换的搜索,只能找到将字符串转换为整数或反之的示例。我想知道如何将其他更复杂的对象进行类型转换...

例如,使用以下类...

class Animal
  attr_accessor :weight, :name
end

class Duck < Animal
  def speak
    'Quack'
  end
end

我希望能够像下面这样做些什么。
irb> animal = Animal.new
irb> duck = (Duck)animal
irb> duck.speak
=> "Quack"

但是我不太清楚如何像Java或类似的语言中那样进行转换。


你在 irb 中输入的最后一条命令是不是应该是 duck.speak - Sagar Pandya
你可以把 Animal 转换成一个模块,包含在 Duck 类(或任何不是 Animal 子类的类)中,并将其转变为动物类。我不熟悉强制类型转换,所以不确定这是否相似? - Sagar Pandya
看一下这个:https://dev59.com/u0_Ta4cB1Zd3GeqPA3JU - Alexandre Angelim
4个回答

2
你需要了解的一件事是,Ruby中类型的概念与对象的类无关。一个对象可以响应多个接口,而不仅仅是它原始的类(例如,通过包含模块或定义单例方法)。因此,不需要将对象强制转换为特定的接口类型。这意味着重要的不是对象什么,而是它什么。
这个概念也适用于字符串和整数。你不需要将字符串强制转换为整数,而是请求字符串对象创建一个新的整数,该整数是字符串在这种形式下的表示。
如果你想进一步了解这个概念,我建议你阅读一个称为鸭子类型的概念。
在你的情况下,你可以直接实例化一个Duck对象,如下所示:
irb> duck = Duck.new
irb> duck.quack
=> "Quack"

2

Ruby中的对象是使用特定类创建的,并且将使用相同类销毁,它永远不会改变。您不能进行强制转换,只能调用函数进行“转换”,这涉及创建新对象或使用另一个对象作为代理的过程。

在您的情况下,您无法进行强制转换,但可以创建具有相同属性的duck:

class Animal
  attr_accessor :weight, :name

  def initialize(options)
    # Allow calling new with either an options hash, or another
    # animal that's intended to be cloned.
    case (options)
    when Animal
      @weight = options.weight
      @name = options.name
    when Hash
      @weight = options[:weight]
      @name = options[:name]
    end
  end
end

class Duck < Animal
  def speak(phrase)
    '%s says %s' % [ name, phrase.inspect ]
  end
end

animal = Animal.new(weight: 10, name: 'Bill')

duck = Duck.new(animal)
puts duck.speak('quack!')

第二种选择是将类似鸭子的功能移动到一个单独的模块中,您可以将其混合到其他类中:
module ActsAsDuck
  def speak
    'Quack!'
  end
end

animal.extend(ActsAsDuck)
puts animal.speak

将该模块中的任何方法混合到对象实例中。

1
据我所知,在Java中,你不能将一个对象转换为其子类。你只能将一个对象转换为其超类或实现的接口。在Ruby中,你不需要进行这种转换。如果你有一个 Duck 的实例,你可以将其视为一个 Animal

1
这个足够接近了吗?
class Animal
  def subclass klass
    klass.new
  end    
end

class Duck < Animal
  def speak
    'Quack'
  end
end

animal = Animal.new
duck = animal.subclass(Duck)
duck.speak
  #=> "Quack"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接