Rubyはミックスイン以外に単一の継承しか許さないと思いました。ただし、クラスSquare
を継承するクラスがある場合Thing
、デフォルトThing
で継承Object
します。
class Thing
end
class Square < Thing
end
これは多重継承を表していないのですか?
Rubyはミックスイン以外に単一の継承しか許さないと思いました。ただし、クラスSquare
を継承するクラスがある場合Thing
、デフォルトThing
で継承Object
します。
class Thing
end
class Square < Thing
end
これは多重継承を表していないのですか?
あなたは多重継承の意味を間違った方法で取っていると思います。おそらく、多重継承としてあなたが心に留めていることは次のようなものです:
class A inherits class B
class B inherits class C
もしそうなら、それは間違っています。それは多重継承とは異なり、Rubyは問題ありません。多重継承が実際に意味するのはこれです:
class A inherits class B
class A inherits class C
そして、あなたは確かにRubyでこれを行うことはできません。
いいえ、多重継承とは、1つのクラスに複数の親クラスがあることを意味します。たとえば、rubyでは、次のようなモジュールを使用してその動作を行うことができます。
class Thing
include MathFunctions
include Taggable
include Persistence
end
したがって、この例では、Thingクラスには、MathFunctionsモジュールのTaggableとPersistenceのメソッドがいくつかありますが、これらは単純なクラス継承では不可能です。
クラスBがクラスAから継承する場合、BのインスタンスはクラスAとクラスBの両方の動作をします。
class A
end
class B < A
attr_accessor :editor
end
Rubyには単一の継承があります。つまり、各クラスには1つだけの親クラスがあります。Rubyはモジュール(MIXIN)を使用して多重継承をシミュレートできます
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp=Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
モジュールAは、メソッドa1とa2で構成されています。モジュールBは、メソッドb1とb2で構成されています。クラスSampleには、モジュールAとBの両方が含まれます。クラスSampleは、4つのメソッドすべて、つまりa1、a2、b1、およびb2にアクセスできます。したがって、クラスSampleが両方のモジュールから継承していることがわかります。したがって、クラスSampleは多重継承またはミックスインを示していると言えます。
多重継承-これは、モジュールを使用していなくても、rubyでは絶対に不可能です。
マルチレベルの継承-これは、モジュールでも可能なことです。
なんで ?
モジュールは、それらを含むクラスの絶対的なスーパークラスとして機能します。
例1:
class A
end
class B < A
end
これは通常の継承チェーンであり、祖先がこれを確認できます。
B.ancestors =>B->A->オブジェクト->..
モジュールによる継承-
例2:
module B
end
class A
include B
end
上記の例の継承チェーン-
B.ancestors =>B->A->オブジェクト->..
これはEx1とまったく同じです。つまり、モジュールBのすべてのメソッドがAのメソッドをオーバーライドでき、実際のクラス継承として機能します。
例3:
module B
def name
p "this is B"
end
end
module C
def name
p "this is C"
end
end
class A
include B
include C
end
A.ancestors => A->C->B->オブジェクト->..
最後の例を見ると、2つの異なるモジュールが含まれていても、それらは単一の継承チェーンにあり、BはCのスーパークラス、CはAのスーパークラスです。
それで、
A.new.name => "this is C"
モジュールCからnameメソッドを削除すると、上記のコードは「thisisB」を返します。これは、クラスを継承するのと同じです。
それで、
どの時点でも、rubyにはマルチレベルの継承チェーンが1つしかないため、クラスの直接の親が複数あることは無効になります。