【C#】オブジェクト指向で重要な4つの概念

アプリケーション構築の一つの理想形である「オブジェクト指向」ですが、これを学ぶのはとても難しく一筋縄ではいかないなと思います。普通にプログラミングをしていく中では、「共通化」までが精一杯であり、アプリケーション全体をオブジェクト指向のもとで構築するのは容易ではありません。

この記事では、オブジェクト指向について少しでも理解を深めるために、調べたこと学んだことをアウトプットしたいと思います。「オブジェクト指向」とはなんぞや?という人やオブジェクト指向について復讐したい人、プログラマーとしてレベルアップしたい人向けの内容になります。

オブジェクト指向とは

オブジェクト指向とは、シンプルに言ってしまうと「機能を分割して必要な処理は、それらを組み合わせて実現しましょう」ということ。ウィキペディアでは以下のように定義されています。

オブジェクト指向プログラミング(オブジェクトしこうプログラミング、英: object-oriented programming、略語:OOP)とは、互いに密接な関連性を持つデータとメソッドをひとつにまとめてオブジェクトとし、それぞれ異なる性質と役割を持たせたオブジェクトの様々な定義と、それらオブジェクトを相互に作用させる様々なプロセスの設定を通して、プログラム全体を構築するソフトウェア開発手法である。

– オブジェクト指向プログラミング(Wikipedia)

とはいえ、この「オブジェクト指向」がとても難しいのです。ある意味でプログラミング、もといアプリケーション構築の理想形と言ってもいいかもしれません。

この記事では筆者のメイン言語であるC#でオブジェクト指向なプログラミングを行うための重要だと思う概念について紹介したいと思います。ここで紹介する概念を根底として、試行錯誤していく末にオブジェクト指向なプログラミングができるようになっていくと思います。

オブジェクト指向の重要な概念

オブジェクト指向で重要になる概念を解説していきます。オブジェクト指向と聞けば難しそうなイメージがあると思いますが、シンプルに核を押さえることは重要になりますので、まずはここから始めましょう。

1,カプセル化

カプセル化とはオブジェクト指向なプログラミングを行う上で欠かせない、オブジェクト(クラス)の設計・実装方針です。ウィキペディアではカプセル化について以下のように定義されています。

一定の関連性を持つデータ(変数、プロパティ、フィールド、属性)と、それらを操作するメソッド(関数)をひとまとめにしてオブジェクトとし、外部に対して必要とされるデータとメソッドのみを公開し、それ以外を内部に隠蔽する仕組みがカプセル化と呼ばれる。

要するにクラス内で保有するデータは限定的なもの・外部から必要なものだけを公開するようすること、また、それらのデータを操作するメソッドもクラス内に記載して必要なものだけを外部に公開するようにする方針です。データとメソッドがクラス内にまとまり、必要なものだけを外部からアクセスできるよう、カプセルに閉じ込めるようなイメージです。そのためカプセル化と呼ばれています。

外部に必要なものだけを公開する仕組みを「情報隠蔽」と言っています。カプセル化をする上で重要にキーワードは以下のようになるかと思います。以下についても調べておくと良いかもしれません。

  • フィールド
  • インスタンス
  • プロパティ(getter、setter)
  • アクセス修飾子(private / public)

外部から必要な情報を受け取る時は、インスタンス化したあとにプロパティで受け渡されるか、コンストラクタの引数としてデータが渡されることが多いような気がしています。

2,継承

スーパークラスで定義した機能をサブクラスで使うことができる機能です。特定のクラスの機能を受け継いで派生クラスを作成するときに使います。ただし多重階層で継承を行うとクラス構造が複雑になり、影響範囲が見えにくくなるといった弊害が問題視されつつあります。

例えばAクラスを継承したBクラスを作成し、さらにBクラスを継承したCクラスを作成したとすると、CクラスにはAクラスとBクラスの機能が継承されていることになります。Cクラスの実装をする際にはAクラスとBクラスの中身を知っていなければりません。

使いどころとしては独自でコントロールをカスタマイズする場合や画面の共通項目を作る場合などにしておき、複数階層での継承を避けるのがよいです。継承する場合は、後述するインターフェースや抽象クラスを使うことが推奨されています。

3,インターフェース

定義のみ記述するクラスのようなもので、定義されたメンバーやメソッドは継承先で実装する必要があります。インターフェースの役割は「約束」や「契約」であり、継承先のクラスで「インターフェースで定義された実装を約束させる」役割を持っていることになります。

4,抽象クラス

実装を記述できるインターフェースのようなもの。インスタンス化することはできず、継承専門のクラスとなります。また、抽象クラスにメソッドを実コードで実装して継承することができます。逆に抽象クラスで定義だけを行い、継承先で実装を強制させることもできます。

インターフェースと抽象クラス

インターフェースと抽象クラスは機能として似たような性質を持ちます。そこで出てくるのが多重継承の問題です。結論から言ってしまうと以下のように違いがあります。

  • インターフェース : クラスに対して多数のインターフェースを継承できる
  • 抽象クラス : クラスに対して1つしか継承を許さない

また別の違いとしてアクセス修飾子の違いがあります。インターフェースはpublic、抽象クラスはpublicまたはprotectedに限定されます。修飾子から考えて、protectedは「そのクラスの内部と派生クラスのインスタンスからアクセス可能」という意味ですので、派生クラスで強制したい実装や共通処理の実装などに向いていると思われます。

オブジェクト指向を学ぶなら

オブジェクト指向はただプログラミングをするだけでは身につかない分野です。一般的にプログラミングをして仕事をするだけでは身に付かない考え方・思考方法だと思っています。オブジェクト指向なプログラミングを学ぶには、自ら能動的にノウハウを学んでいくしかありません。

筆者はオンライン講座の「Udemy」で取っかかりを学びました。私が実際に受講したのは、ピーコックアンダーソンさんの「C#でオブジェクト指向をする方法」という講座です。オブジェクト指向プログラミングは難しく、日常的な案件では触れることの少ない概念ですので、こうした講座を利用して知識と実践を積んでいくしかないと思います。

C#という言語を使ってスキルアップしたい人は受講しておいて損のない内容です。この講座はC#の実践を交えながら、オブジェクト指向プログラミングの重要な考え方を紹介しています。対象レベルは初級から中級へステップアップしたい人、または中級レベルで基礎固めをもう一度したい人になるかと思います。

【Udemy】「C#でオブジェクト指向をする方法」レビュー」の記事では筆者が受講して感じたことや内容をレビューしているので参考にしてもらえればと思います。また以下のボタンから講座の概要もチェックできますので、興味のある人はチェックしてみてください。

オブジェクト指向は難しい

ここまでオブジェクト指向に必要な概念などを駆け足で紹介してきました。ここまで見てきてわかるように、オブジェクト指向はプログラミング言語が理解できて初めて実践できると思います。

Udemyの講座では「普通のプログラマーは、せいぜい共通化で止まってしまう。オブジェクト指向を身に着けるには、教えてもらうか学ぶしかない」と言っていて、この考え方は正しいなと思います。プログラマーとしての考え方ではなく、アプリケーション全体の構造や機能が見えていないとオブジェクト指向な設計は難易度が高いからだと思います。

ある意味でオブジェクト指向はプログラマーが目指す一つの理想形であり、そこに行き着くまでは能動的に学習を続けて、自分なりに試行錯誤する必要があると感じました。これからもこのブログでのアウトプットを通じて、自身のプログラミングによる表現力を高めていきます。