你如何在Ruby中做多态?

Fly*_*wat 14 c# ruby polymorphism

在C#中,我可以这样做:

class Program
{
    static void Main(string[] args)
    {
        List<Animal> animals = new List<Animal>();

        animals.Add(new Dog());
        animals.Add(new Cat());

        foreach (Animal a in animals)
        {
            Console.WriteLine(a.MakeNoise());
            a.Sleep();
        }
    }
}

public class Animal
{
    public virtual string MakeNoise() { return String.Empty; }
    public void Sleep()
    {
        Console.Writeline(this.GetType().ToString() + " is sleeping.");
    }
}

public class Dog : Animal
{
    public override string MakeNoise()
    {
        return "Woof!";
    }
}

public class Cat : Animal
{
    public override string MakeNoise()
    {
        return "Meow!";
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,输出是(略有释义):

  • 狗在睡觉
  • 猫在睡觉

由于C#经常因其冗长的类型语法而被模拟,你如何处理像duck这样的鸭子类型语言中的多态/虚方法?

Mik*_*use 22

到目前为止,所有答案对我来说都很好.我想我只是提到整个遗产并不是完全必要的.暂时排除"睡眠"行为,我们可以使用duck-typing实现整个期望的结果,并且省略了创建Animal基类的需要.谷歌搜索"鸭子打字"应该产生任何数量的解释,所以在这里,我们只是说"如果它像鸭子一样走路,像鸭子一样嘎嘎叫......"

可以通过使用mixin模块来提供"睡眠"行为,例如Array,Hash和其他Ruby内置类,包括Enumerable.我并不是说它必然更好,只是一种不同的,也许是更具惯用性的Ruby方式.

module Animal
  def sleep
    puts self.class.name + " sleeps"
  end
end

class Dog
  include Animal
  def make_noise
    puts "Woof"
  end
end

class Cat
  include Animal
  def make_noise
    puts "Meow"
  end
end
Run Code Online (Sandbox Code Playgroud)

你知道其余的......

  • +1用于混合 - 使用常用功能而不是继承它.虽然这两种方法都有效,但这更像是"Ruby的做法"(对于这个特定的例子). (2认同)

Joh*_*kin 15

编辑:为更新的问题添加了更多代码

免责声明:我在一年左右的时间里没有使用过Ruby,也没有在这台机器上安装过Ruby,因此语法可能完全错误.但这些概念是正确的.


完全相同的方式,使用类和重写方法:

class Animal
    def MakeNoise
        return ""
    end
    def Sleep
        print self.class.name + " is sleeping.\n"
    end
end

class Dog < Animal
    def MakeNoise
        return "Woof!"
    end
end

class Cat < Animal
    def MakeNoise
        return "Meow!"
    end
end

animals = [Dog.new, Cat.new]
animals.each {|a|
    print a.MakeNoise + "\n"
    a.Sleep
}
Run Code Online (Sandbox Code Playgroud)

  • 布伦特:那将是"由Python用户记住的Ruby" (4认同)

man*_*eru 10

使用惯用的Ruby

class Animal
  def sleep
    puts "#{self.class} is sleeping"
  end
end

class Dog < Animal
  def make_noise
    "Woof!"
  end
end

class Cat < Animal
  def make_noise
    "Meow!"
  end
end

[Dog, Cat].each do |clazz|
  animal = clazz.new
  puts animal.make_noise
  animal.sleep
end
Run Code Online (Sandbox Code Playgroud)