Ruby,多态,继承和self.class

时间:2014-04-13 16:32:13

标签: ruby inheritance polymorphism

我对红宝石很新。我已经习惯了Java和C ++。我试图理解的是如何使用该语言的多态性。还有继承规则。我制作了一个简单的工作代码,但我无法理解它有多好。还有其他方法吗?据我所知,红宝石总有其他方法。

它的作用:比较儿童,如果他们属于同一个班级。否则将它们与父母进行比较。

很抱歉,如果我浪费了你的时间。谷歌搜索没有帮助,我不能提出一个好的查询。

class Hero
public 
#redefine comparison like this just for the sake of having it use protected method
def <=> hero 
    @mass <=> hero.get_mass
end

def initialize mass
    @mass = mass
end

protected
#this protected method is used for inheritance testing purposes
def get_mass
    @mass
end

end

class Finn < Hero

def initialize mass, sword_length
    @mass = mass
    @sword_length = sword_length
end
    # THIS! Am I doing this right?
def <=> finn
    if finn.class == self.class
        (@mass+@sword_length) <=> (finn.get_mass+finn.get_sword_length)
    else
        super(finn)
    end 
end
    # probably not...
protected

def get_sword_length
    @sword_length
end
end

class Jake < Hero

def initialize mass, fist_length
   @mass = mass
   @fist_length = fist_length
end

def <=> jake
    if jake.class == self.class
        (@mass+@fist_length) <=> (jake.get_mass+jake.get_fist_length)
    else
        super(jake)
    end
end

protected

def get_fist_length
    @fist_length
end

end

hero1 = Finn.new(10, 80)
hero4 = Jake.new(50, 18)
puts " error?  "+(hero1<=>hero4).to_s

2 个答案:

答案 0 :(得分:0)

我试图重构你的代码,它的外观如下: -

class Hero
  attr_reader :mass
  #  more info in attr_reader and attr_accessor is here http://stackoverflow.com/questions/5046831/why-use-rubys-attr-accessor-attr-reader-and-attr-writer

  def initialize mass
    @mass = mass
  end

  def <=> hero
    mass <=> hero.mass
  end
end

class Finn < Hero
  attr_reader :sword_length

  def initialize mass, sword_length
    @sword_length = sword_length
    super(mass)
  end

  def <=> finn
    if finn.class == self.class
      (@mass+@sword_length) <=> (finn.mass+finn.sword_length)
    else
      super(finn)
    end
  end
end

class Jake < Hero
  attr_reader :fist_length

  def initialize mass, fist_length
    @fist_length = fist_length
    super(mass)
  end

  def <=> jake
    #alternate dense way to do it
    jake.class == self.class ? ((@mass+@fist_length) <=> (jake.mass+jake.fist_length)) : super(jake)
  end

end

hero1 = Finn.new(10, 80)
hero4 = Jake.new(50, 18)
puts " error?  "+(hero1<=>hero4).to_s

答案 1 :(得分:0)

几点说明:

通常,您将使用与实例变量同名的访问者而不是get样式命名。

通常你不会检查类,而是检查对象可以做什么。

class Hero
  def initialize(mass)
    @mass = mass
  end

  def <=>(hero)
    mass <=> hero.mass
  end

  protected #I put this as protected since you did, but I would likely leave it public

  attr_reader :mass
end


class Finn < Hero
  def initialize(mass, sword_length)
    @mass = mass
    @sword_length = sword_length
  end

  def <=>(finn)
    if finn.respond_to? :sword_length
      (mass + sword_length) <=> (finn.mass + finn.sword_length)
    else
      super(finn)
    end
  end

  protected

  attr_reader :sword_length
end


class Jake < Hero

  def initialize(mass, fist_length)
    @mass = mass
    @fist_length = fist_length
  end
  #edited 
  def <=>(jake)
    if jake.respond_to? :fist_length
      (mass + fist_length) <=> (jake.mass + jake.fist_length)
    else
      super(jake)
    end
  end

  protected

  attr_reader :fist_length
end