プログラミング言語のクラスと継承まとめ

プログラミング

プログラミングをチームで効率よく開発するためには、担当領域を決めたり、似たようなコードが作らないようにするなどの工夫が必要となります。

プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念がクラスです。

適切なクラス分割を行うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。

プログラミング初心者にとっては、理解が難しい分野ではありますが、チームで開発するプログラマとなるためには必須の知識となります。

本ブログではこれまでに、JavaScript、Python、Java、Ruby、Goのクラスと継承について解説してきました。

本記事では、クラスと継承の各項目ごとに各言語の実装状況や特徴についてまとめます。

言語による違いが分かったり、忘れてしまったときの復習用として役立つ内容になっていますので、ぜひ最後までご覧いただければと思います。

最後に各言語のソースコードを含む詳細内容を確認できる関連ページへのリンクも用意しておきますので、気になる方はチェックしてみてください。

プログラミング言語のクラスと継承まとめ

クラスと継承に関する項目として、以下の内容を採り上げます。
なお、Goについてはクラスと継承の概念がないので、近しい機能として代替できる構造体とインタフェースに置き換えて説明します。

  • クラスの定義方法
  • コンストラクタ
  • インスタンス化
  • メソッド
  • 変数
  • アクセッサ
  • 継承

クラスの定義方法

言語 クラスの定義方法
JavaScript
  • class キーワードの後にクラス名を指定
Python
  • class キーワードの後にクラス名を指定
Java
  • class キーワードの後にクラス名を指定
Ruby
  • class キーワードの後にクラス名を指定
Go
  • type キーワードの後にクラス名 struct キーワードを指定する

クラスの定義方法は、どの言語でもほぼ同じで、classキーワードによって宣言します。

どの言語もクラス名の先頭は大文字にするパスカルケース(アッパーキャメルケース)が慣習となっています。

コンストラクタ

言語 コンストラクタ
JavaScript
  • constructorメソッドを定義
Python
  • __init__メソッドを定義
Java
  • クラス名と同名のメソッドを定義
Ruby
  • initializeメソッドを定義
Go
  • 特に決まりはないが、構造体名の先頭にnewを付けるのが慣習

コンストラクタの定義は、どの言語とも一定の決まりがあります。

Goについては明示的なコンストラクタという概念はないですが、構造体を作成する関数として作成する慣習があります。

インスタンス化

言語 インスタンス化
JavaScript
  • new の後にクラスを指定して作成
Python
  • クラス名を指定して作成
Java
  • new の後にクラスを指定して作成
Ruby
  • クラスの new メソッドを呼出して作成
Go
  • コンストラクタを呼出す、または直接構造体を作成

JavaScript、Java、Rubyはnew演算子またはnewメソッドによって作成します。

Pythonには __new__ メソッドはありますが、インスタンス生成を行うにはクラス名だけで作成できます。

メソッド

言語 メソッド
JavaScript
  • メソッド:インスタンス化してアクセスする。
  • 静的メソッド:インスタンス化しなくてもアクセスできる。staticキーワードによって定義する。
Python
  • インスタンスメソッド:インスタンス化してアクセスする。
  • クラスメソッド:インスタンス化しなくてもアクセスできる。@classmethodをメソッド定義に付ける。第一引数に呼出しクラスを受け取る。
  • 静的メソッド:インスタンス化しなくてもアクセスできる。@staticmethodをメソッド定義に付ける。
Java
  • インスタンスメソッド:インスタンス化してアクセスする。
  • 静的メソッド:インスタンス化しなくてもアクセスできる。staticキーワードによって定義する。
Ruby
  • インスタンスメソッド:インスタンス化してアクセスする。
  • クラスメソッド:インスタンス化しなくてもアクセスできる。メソッド名の先頭にselfを付けて定義する。
Go
  • メソッド:構造体を作成してアクセスする。

JavaScript、Java、Rubyは、呼び方は違えどインスタンス化して利用するメソッドと、インスタンス化しなくても利用できるメソッドの2種類があります。

Pythonは3種類のメソッドがあります。クラスメソッドと静的メソッドはほぼ同じで、クラスメソッドで両方の役割を満たせるかと思うので、静的メソッドはあまり使う機会はないかもしれません。

変数

言語 変数
JavaScript
  • プロパティ:インスタンス化してアクセスする。
Python
  • インスタンス変数:インスタンス化してアクセスする。メソッド内でselfに対して定義する。
  • クラス変数:インスタンス化しなくてもアクセスできる。メソッド外で定義する。
Java
  • インスタンス変数:インスタンス化してアクセスする。メソッド外で定義する。
  • 静的変数:インスタンス化しなくてもアクセスできる。メソッド外でstaticキーワードを付けて定義する。
Ruby
  • インスタンス変数:インスタンス化してアクセスする。変数名の先頭に@を付けて定義する。
  • クラス変数:インスタンス化しなくてもアクセスできる。変数名の先頭@@を付けて定義する。
Go
  • フィールド変数:構造体を作成してアクセスする。構造体定義内に変数を定義する。

変数定義も言語によって種類があり、大きくインスタンス化してアクセスする変数とインスタンス化しなくてもアクセスできる変数に大別されます。

インスタンス化しなくてもアクセスできる変数は、値を書き換えるとすでに作成したインスタンスにも影響を及ぼすので、基本的には書き換えることのない定数などに用いるのが良いと思います。

変数のスコープの話はここでは割愛していますが、実際にはローカル変数も加え、スコープを最小限にする工夫をしながら各変数を使っていくことをおすすめします。

アクセッサ

言語 アクセッサ
JavaScript
  • メソッド名を「get プロパティ名」または「set プロパティ名」とすることで自動的にアクセッサとなる。
Python
  • メソッド定義に@propertyを付けるとgetterになる。
  • メソッド定義に@変数名.setterを付けるとsetterになる。
Java
  • 自分で実装する必要がある。
  • メソッド名の先頭にgetterならget、setterならsetを付ける慣習がある。
Ruby
  • インスタンス変数にattr_accessorとして定義する読み書き可能なアクセッサとなる。
  • インスタンス変数にattr_writerとして定義する書込のみ可能なsetterとなる。
  • インスタンス変数にattr_readerとして定義する参照のみ可能なgetterとなる。
Go
  • 自分で実装する必要があるが、外から直接アクセスすることが可能。

言語によってアクセッサの作り方が決まっているものもあります。

アクセッサは変数のスコープや値チェック等と併せて、作るのかどうかや作り方を決定していくと良いです。

継承

言語 継承
JavaScript
  • extendsキーワードの後に親クラスを指定して定義する。
  • 親クラスのメソッドやプロパティには super を使ってアクセスすることができる。
Python
  • クラス名の後の括弧に親クラスを指定して定義する。
  • 親クラスのメソッドには super を使ってアクセスすることができる。
  • 複数のクラスを継承する多重継承が可能。
Java
  • extendsキーワードの後に親クラスを指定して定義する。
  • 親クラスのメソッドやプロパティには super を使ってアクセスすることができる。
  • 抽象クラスや抽象メソッドを使って、子クラスに実装を強制することができる。
Ruby
  • クラス名の後に < と親クラスを指定して定義する。
  • 親クラスと同盟のメソッドには super を使ってアクセスすることができる。
Go
  • 構造体の埋め込みによって継承しているように見せることができる。
  • インタフェースを実装するとポリモーフィズムのような動作をさせることができる。

クラスの継承は各言語ともに親クラスのメソッドや変数をそのまま引き継ぎ、必要なところをオーバーライドして書き換えることができます。

子クラスから親クラスが持つメソッドや変数をアクセスできる範囲は、言語によって多少異なるので注意が必要です。

今回は割愛していますが、mixinやインタフェースなどを使うことで、さらに高度なクラス設計ができるようになります。

良いプログラマになるにはクラス設計が重要

プログラマは単にプログラミングするだけではなく、設計ができることも重要です。

チームで効率よく開発を進めるには、どんなクラス設計、継承関係、クラス間連携とするのかは重要な要素です。

クラス分割をしたり、オブジェクト指向でプログラミングするのは難しいかもしれませんが、普段から目に見えるものがどんな関係があるか、どんな振る舞いを持っているのかを考えてみると良い訓練になると思います。

良い設計ができるプログラマを目指して行きましょう。

 

今回はクラスと継承の各項目ごとに各言語の実装状況や特徴についてまとめてみました。

以下にソースコードも含めた各言語の詳細を記述した関連ページヘのリンクをまとめておくので、気になる方はチェックしてみてください。

以上、参考になれば幸いです。

関連記事

JavaScriptのクラスと継承【プログラミング初心者向け教材】
プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念がクラスです。 適切なクラス分割を行うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。 チームで開発するプログラマとなるためには必須の知識となります。 本記事では、JavaScriptのクラスと継承についてまとめます。
Pythonのクラスと継承【プログラミング初心者向け教材】
プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念がクラスです。 適切なクラス分割を行うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。 チームで開発するプログラマとなるためには必須の知識となります。 本記事では、Pythonのクラスと継承についてまとめます。
Javaのクラスと継承【プログラミング初心者向け教材】
プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念がクラスです。 適切なクラス分割を行うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。 チームで開発するプログラマとなるためには必須の知識となります。 本記事では、Javaのクラスと継承についてまとめます。
Rubyのクラスと継承【プログラミング初心者向け教材】
プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念がクラスです。 適切なクラス分割を行うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。 チームで開発するプログラマとなるためには必須の知識となります。 本記事では、Rubyのクラスと継承についてまとめます。
Goの構造体とインタフェース【プログラミング初心者向け教材】
プログラムを役割や機能に応じて分割することをモジュール分割と言ったりしますが、その際に必要となる概念が構造体です。 適切に構造体を扱うことで、無駄がなくて読みやすく、メンテナンスのしやすいプログラムにすることができます。 チームで開発するプログラマとなるためには必須の知識となります。 本記事では、Goの構造体とインタフェースについてまとめます。

コメント

タイトルとURLをコピーしました