Ruby 支持包含多态吗
Ruby 支持“包含多态性”吗?这和鸭子打字一样吗?
如果不是,Ruby 中的多态性和鸭子类型有什么区别?
有人可以用我下面的例子来说明吗:
# superclass - inheritance
class Animal
def make_noise
# define abstarct method (force override)
raise NoMethodError, "default make_noise method called"
end
end
# module - composition
module Fur
def keep_warm
# etc
end
end
# subclass = is-a relationship
class Bird < Animal
# override method - polymorphism
def make_noise
"Kaaw"
end
end
class Cat < Animal
# module mixin = has-a relationship
include Fur
def make_noise
"Meow"
end
end
class Radio
# duck typing (no inheritance involved)
def make_noise
"This is the news"
end
end
class Coat
include Fur
end
animals = [Bird,Cat,Radio,Coat,Animal]
animals.each do |a|
# polymorphism or duck typing?
obj = a.new
if obj.respond_to? 'make_noise'
puts obj.make_noise
end
end
Does Ruby support "inclusion polymorphism"? Is this the same as Duck Typing?
If not, what is the difference between polymorphism and duck-typing in Ruby?
Can someone please illustrate with my example below:
# superclass - inheritance
class Animal
def make_noise
# define abstarct method (force override)
raise NoMethodError, "default make_noise method called"
end
end
# module - composition
module Fur
def keep_warm
# etc
end
end
# subclass = is-a relationship
class Bird < Animal
# override method - polymorphism
def make_noise
"Kaaw"
end
end
class Cat < Animal
# module mixin = has-a relationship
include Fur
def make_noise
"Meow"
end
end
class Radio
# duck typing (no inheritance involved)
def make_noise
"This is the news"
end
end
class Coat
include Fur
end
animals = [Bird,Cat,Radio,Coat,Animal]
animals.each do |a|
# polymorphism or duck typing?
obj = a.new
if obj.respond_to? 'make_noise'
puts obj.make_noise
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在你的例子中,你可以说每个循环的工作归功于鸭子类型(与客户端代码只关心变量是否会发出噪音有关),但猫和鸟可以发出噪音这一事实是一个理论描述称为多态性的子类化机制。
因此,您可以说多态性和鸭子类型之间的区别在于,多态性是您可以在任何情况下使用声称是某种类型的对象来代替另一个对象的想法,但鸭子类型是您不这样做的想法关心对象的类型,只要它实现了某个接口即可。
例如,在 Java 中,如果你创建 Animal 的子类,你可以期望它不仅会发出噪音,而且还会有与动物相关的其他行为,而在 Ruby 中,对象可以发出噪音这一事实并不意味着它会发出噪音。不依赖于类型,只依赖于特定方法的存在。
当然,在 Java 中,您有接口的概念,它为相同的模式提供了(静态)机制。
恕我直言,最重要的区别是名称背后不同的编程哲学,而不是概念本身。
我想这一切都归结于这样一个事实:多态性一词与更结构化的 OOP 思想相关,而 Ruby 必须为一种具有不同可能性和含义的编程方式发明一个名称。
Well in your example, you could say that the each loop works thanks to duck typing (related to the fact that the client code only cares if the variable can make noise), but the fact that Cats and Birds can make noise is a theoretycal description of the subclassing mechanism known as polymorphism.
So you could say that a difference between polymorphism and duck typing is that polymorphism is the idea that you can use an object that claims to be a certain type in place of another in any circumstances, but duck typing is the idea that you don't care about the type of the object, as long as it implements certain interface.
So for instance in Java, if you make a subclass of Animal, you can expect it not only to make noise, but also to have other behaviour associated to animals, while in the case of Ruby, the fact that an object can make noise doesn't depend on the type, just on the existence of a particular method.
Of course in Java you have the concept of interfaces that give a (static) mechanism for the same pattern.
The most important difference IMHO is different programming philosophies behind the names, not so much in the concepts themselves.
I guess it all comes down to the fact that the term polymorfism is associated with more structured OOP ideas, while Ruby had to invent a name for a way of programming which has different posibilities and implications.