Rubyのクラスを勉強するため、C++と比較しながら考えてみました。
あくまでC++erがRubyを理解をしやすくするためのイメージという感じです。
クラス宣言
どちらも似たようなもん。
Ruby
class Foo
end
C++
class Foo
{
};
初期化
RubyはinitializeメソッドがC++のコンストラクタに相当するもの。(オブジェクトの生成時に自動的に呼び出される)
ちなみにC++のデストラクタに相当するものはRubyにはない。(やろうと思えばできるみたい)
Ruby
class Foo
def initialize
#初期化処理
end
end
C++
class Foo
{
Foo();
};
//コンストラクタ
Foo::Foo()
{
//初期化処理
}
継承
どちらも似たようなもん。
ただしRubyは多重継承ができない。(できない方がいいかもだけど)
厳密には異なるが、似たような機能としてMix-inがある。
Ruby
class SuperFoo
end
class Foo < SuperFoo
end
C++
class SuperFoo
{
};
class Foo : SuperFoo
{
};
オーバーライド
どちらも似たようなもん。
Ruby
class SuperFoo
def method
end
end
class Foo < SuperFoo
def method
end
end
C++
class SuperFoo
{
virtual void method();
};
void SuperFoo::method()
{
}
class Foo : SuperFoo
{
void method() override;
};
void Foo::method()
{
}
継承元のメソッドを使いたい時
継承元のメソッドをオーバーライドしたメソッド内で使いたい場合、
Rubyはsuperと記述するだけで継承元のメソッドを呼び出すことが可能。
Ruby
class Foo < SuperFoo
def method
super;
end
end
C++
void Foo::method()
{
SuperFoo::method();
};
引数のあるメソッドのオーバーライド
引数のあるメソッドの場合でも、superと書くだけでオーバーライドしたメソッドの引数を
継承元のメソッドに引数として渡してくれる。
class SuperFoo
def method(str)
end
end
class Foo < SuperFoo
def method(str)
super
end
end
引数を渡したくない時
初期値を使いたい等で引数を渡したくない場合、空の()を入れることで引数を渡さなくなる。
class SuperFoo
def method(str = "Foo")
end
end
class Foo < SuperFoo
def method()
super()
end
end
クラス変数
C++だとこの機能に似たようなものが存在しない?(知らないだけかも)
機能を簡単に説明すると、同じクラスのオブジェクトで共通して使え、スコープはクラス内のみという変数。
C++では静的変数をクラス内で宣言することで似たような処理を行える。(2015/11/2 追記)
class Foo
@@count = 0
def initialize
@@count += 1
end
def count
return @@count
end
end
foo1 = Foo.new
p foo1.count #1が出力される
foo2 = Foo.new
p foo2.count #2が出力される
p foo1.count #2が出力される
class Foo {
public:
Foo();
static int getInstanceCount(){ return count; };
private:
static int count;
};
int Foo::count = 0;
Foo::Foo(){
count += 1;
}
int main() {
std::cout << Foo::getInstanceCount() << endl; //0が出力される
Foo f1;
std::cout << Foo::getInstanceCount() << endl; //1が出力される
Foo f2;
std::cout << Foo::getInstanceCount() << endl; //2が出力される
return 0;
}
インスタンス変数・インスタンスメソッド
Rubyでは変数名の先頭に@を付けた変数がインスタンス変数となる。
Ruby
class Foo
def initialize
@count = 0 #インスタンス変数
end
def print #インスタンスメソッド
puts count
end
end
C++
class Foo()
{
Foo();
void print();
private:
int m_count;//インスタンス変数(メンバ変数)
};
Foo::Foo() :m_count(0)
{
}
void Foo::print() //インスタンスメソッド
{
std::cout<< m_count << endl;
}
クラスメソッド
C++でいえば静的関数に相当するもの。
Ruby
class Foo
def Foo.power2( num ) #クラスメソッド
return num*num
end
end
p Foo.power2( 10 ) #インスタンス無しで呼び出せる 100が出力される
C++
class Foo()
{
static double power2( const int num ){ return num*num; };
};
main()
{
std::cout<< Foo::power2( 10 ) << endl; //インスタンス無しで呼び出せる 100が出力される
}