看到许多地方写到,ruby的mixin可以完美解决c++多继承带来的问题。(包括一本著名的书《programing ruby》),而对怎么解决,却常常语焉不详
我就纳闷了,哪里解决了?该出现的问题还是会出现,而且更难发现了。
首先先回忆一下c++多继承导致的问题
一个类,同时继承两个类,两个类里变量名重复或者方法名重复(除非是private访问控制权限),此时编译器就会不知道该名字对应的是哪个。
问题很简单,就是一个名字映射到了多个对象。看上去只要分两个名字就能轻松解决了,但是在大型软件系统中,类的结构非常复杂,如果滥用多继承导致出了问题,排错将是相当困难的。
多继承问题的解决方案现在主要有
类似java的单继承多接口,因为接口本身没有实现,所以多接口方法名字重复了也没问题。不过事实上现实世界本来就是多继承的,该方法有时就可能导致重复的代码。
设计模式中的组合,这个相当于是手动把多个父类的方法混到一个类里,问题也很明显,大量重复编码,而且会导致多节的调用(kotlin采用by解决了这个问题)
接下来说说ruby或者类似动态语言的(例如js的原型链),这些动态语言所谓对多继承解决的方案都是,直接覆盖重名方法。
如图
module A
def test1
puts "1233"
end
end
module B
def test1
puts "2554"
end
end
class Test
include A
include B
end
Test.new.test1
可以看出,有一个同名方法被后来的方法覆盖了
而同样的问题,在c++中会编译出错,所以ruby这个mixin算是解决多继承的问题吗?
其实我觉得这种隐式的覆盖而不是直接的报错,反而会使可能的错误更加严重,因为难以排查(有遇到这种重名直接覆盖导致程序逻辑bug的同学应该深有体会)。
类似js这种原型链的继承,也会出现这种隐式覆盖问题。所以我觉得ruby的mixin,根本就不能解决多继承的问题,还是需要谨慎使用。
欢迎关注我的github
https://github.com/luckyCatMiao