Ruby Language
継承
サーチ…
構文
- クラスSubClass <SuperClass
継承を使用するための既存のクラスのリファクタリング
Cat
とDog
2つのクラスがあるとしましょう。
class Cat
def eat
die unless has_food?
self.food_amount -= 1
self.hungry = false
end
def sound
puts "Meow"
end
end
class Dog
def eat
die unless has_food?
self.food_amount -= 1
self.hungry = false
end
def sound
puts "Woof"
end
end
eat
メソッドは、これらの2つのクラスでまったく同じです。これが機能している間は、維持するのは難しいです。同じeat
方でもっと動物がいれば問題は悪化します。継承はこの問題を解決することができます。
class Animal
def eat
die unless has_food?
self.food_amount -= 1
self.hungry = false
end
# No sound method
end
class Cat < Animal
def sound
puts "Meow"
end
end
class Dog < Animal
def sound
puts "Woof"
end
end
私たちは新しいクラスAnimal
を作成し、そのクラスにeat
メソッドを移しました。そして、 Cat
とDog
、この新しい共通スーパークラスから継承しました。これにより、コードを繰り返す必要がなくなります
多重継承
多重継承は、あるクラスが複数のクラス(つまり、複数の親)から継承できるようにする機能です。 Rubyは多重継承をサポートしていません。単一継承(つまりクラスは親を1つしか持てません)をサポートしていますが、 合成を使用してモジュールを使用してより複雑なクラスを構築することができます。
サブクラス
継承により、クラスは既存のクラスに基づいて特定の動作を定義できます。
class Animal
def say_hello
'Meep!'
end
def eat
'Yumm!'
end
end
class Dog < Animal
def say_hello
'Woof!'
end
end
spot = Dog.new
spot.say_hello # 'Woof!'
spot.eat # 'Yumm!'
この例では:
-
Dog
はAnimal
から継承し、それをサブクラスにします。 -
Dog
はsay_hello
メソッドとeat
メソッドの両方をAnimal
からsay_hello
します。 -
Dog
は、異なる機能を持つsay_hello
メソッドをオーバーライドします。
ミックスイン
ミックスインは、複数の継承に似た何かを実現する美しい方法です。これは、モジュールで定義されたメソッドを継承するか、むしろクラスに含めることを可能にします。これらのメソッドは、インスタンスメソッドまたはクラスメソッドとして含めることができます。以下の例は、この設計を示しています。
module SampleModule
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def method_static
puts "This is a static method"
end
end
def insta_method
puts "This is an instance method"
end
end
class SampleClass
include SampleModule
end
sc = SampleClass.new
sc.insta_method
prints "This is an instance method"
sc.class.method_static
prints "This is a static method"
継承されるものは何ですか?
メソッドは継承されます。
class A
def boo; p 'boo' end
end
class B < A; end
b = B.new
b.boo # => 'boo'
クラスメソッドは継承されます
class A
def self.boo; p 'boo' end
end
class B < A; end
p B.boo # => 'boo'
定数は継承されます。
class A
WOO = 1
end
class B < A; end
p B::WOO # => 1
しかし、注意してください、彼らはオーバーライドすることができます:
class B
WOO = WOO + 1
end
p B::WOO # => 2
インスタンス変数は継承されます:
class A
attr_accessor :ho
def initialize
@ho = 'haha'
end
end
class B < A; end
b = B.new
p b.ho # => 'haha'
super
を呼び出さずにインスタンス変数を初期化するメソッドをオーバーライドすると、それらはゼロになります。上からの続き:
class C < A
def initialize; end
end
c = C.new
p c.ho # => nil
クラスのインスタンス変数は継承されません:
class A
@foo = 'foo'
class << self
attr_accessor :foo
end
end
class B < A; end
p B.foo # => nil
# The accessor is inherited, since it is a class method
#
B.foo = 'fob' # possible
クラス変数は実際に継承されません
これらは基本クラスとすべてのサブクラスで1つの変数として共有されます。
class A
@@foo = 0
def initialize
@@foo += 1
p @@foo
end
end
class B < A;end
a = A.new # => 1
b = B.new # => 2
上から続きます:
class C < A
def initialize
@@foo = -10
p @@foo
end
end
a = C.new # => -10
b = B.new # => -9