LoginSignup
5

More than 5 years have passed since last update.

25行でC#のオブジェクト指向がわかった気になる

Last updated at Posted at 2018-12-09

25行でC#のオブジェクト指向がわかった気になる

この物語はいつもLinuxでC書いてるプログラマが急にC#の案件を振られ、勉強のためいろいろコードを書いていたら、なんとなくオブジェクト指向がわかった気になる過程を淡々と描くものです。間違ってるかもしれないので過度な期待はしないでください。

前提知識

端々にCとの比較が出てきますが、Cの入門書をちょっとでもかじっていれば問題ないと思います。

注意!!

これはあくまでも自分がオブジェクト指向という考え方を勉強し、納得する過程をなぞったものであり、厳密な定義とは異なる解釈をしている場合があります。

まずは簡単な文法を確認

オブジェクト指向言語触るの初めて(´・ω・`)

クラス

class クラス名 {
  static void Main() {
    // 処理とかいろいろ
  }
}

ふむふむ。なんとなくJavaとかC++でclassなんとかって書いてあるの見た気がする。

名前空間

namespace HelloWorld {
  class Program {
    // 処理とかいろいろ
  }
}

namespace?まあ、キーワード名からして#ifndef __MYLIB_H__って書かなくても変数名とか関数名が衝突しないようにするためのものかな。

hello worldでも書いてみるか

hello1.cs
using System;

namespace HelloWorld {
  class Program {
    static void Main() {
      Console.WriteLine("Hello World");
    }
  }
}

コンパイルして実行。別にVisual Studioからでもいいけど、Vim大好きだから。Vim大好きだから!

C:\CSharp> csc hello1.cs
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
Copyright (C) Microsoft Corporation. All rights reserved.

C:\CSharp> hello1.exe
Hello World

C:\>

おーけーおーけー

変数作ってみる

hello2.cs
using System;

namespace HelloWorld {
  class Program {
    static void Main() {
      int i;
      int[] a = new int[5];

      for (i = 0; i < a.Length; i++) {
        a[i] = i * 100;
        Console.WriteLine("a[{0}] = {1}", i, a[i]);
      }
    }
  }
}

変数作って、配列作って、fora[]の全要素にアクセスしてる。a.Lengthはオブジェクト指向っぽい書き方だな。

ん?

int i;はCと同じ書き方なのにnew int[5]ってなんだ?

int inew int[5]の違い

Microsoftのドキュメントを開く。→ 共通型システム
C#の型は値型参照型に大きく分けられる、と。

参照型?難しそうな言葉出てきた Oo(´・ω・`)

要は、値型は数字の型とstructで定義されたもので、参照型はclassで定義されたもの、と。structで定義される構造体はCでも勝手にメモリーが割り当てられる。classは自分でメモリーをnewで割り当てる必要がある。malloc()のC#版がnewか。しかもガーベッジコレクションが勝手に不要になったメモリー回収するからfree()不要。(Cも構造体の中にポインターがあってmallocするとかは一旦忘れて)

つまりあれか、参照型はCのポインターみたいなもんか!

色んな人に怒られそうなザックリ理解(´∀`;)

注意!!

厳密には違います。int型はSystem.Int32のエイリアス(別名)でしかなく、stringSystem.Stringのエイリアスです。C#では源泉を辿っていくとすべてのクラスはSystem.Objectの派生になっています。正確には値型はSystem.ValueTypeを継承するクラス、参照型はそれ以外にSystem.Objectクラスから脈々と派生してできたクラス。

クラスを作ってみる

hello3.cs
using System;

namespace HelloWorld {
  class SuperText {
    public string AddWorld(string s) {
      return s + " World";
    }
  }

  class Program {
    static void Main() {
      string s;
      SuperText t = new SuperText();

      s = Console.ReadLine();
      s = t.AddWorld(s);

      Console.WriteLine(s);
    }
  }
}

SuperText t = new SuperText();はさっき調べたように、クラスだからnewでインスタンスを作る。Console.ReadLine()はCのscanf()みたいなやつ。Console.WriteLine()printf()みたいなやつ。

s = t.AddWorld();SuperTextクラスのAddWorld()を呼び出してるんだな?見に行くぞ。

public string AddWorld(string s) {は文字列型の引数を取って、外部からアクセスできるようにpublicになってる関数(C#ではメソッドと言う)だな。privateと書くと他のクラスから使えなくなる。Cではファイル単位でやっていたアクセス制限をC#ではクラスと言う単位でやってる。

あれ?

オブジェクト指向って確か、データとそれを操作するメソッドを合わせたものじゃなかったっけ?string sがボッチになっとる。

オブジェクト指向になる

つまり、SuperTextクラスにstring sAddWorld()の両方を入れればいい。

hello4.cs
using System;

namespace HelloWorld {
  class SuperText {
    private string str;

    public void AddWorld(string s) {
      str = s + " World";
    }

    public string GetResult() {
      return str;
    }
  }

  class Program {
    static void Main() {
      SuperText t = new SuperText();

      t.AddWorld(Console.ReadLine());

      Console.WriteLine(t.GetResult());
    }
  }
}

今度はSuperTextクラスの中にデータを保存するstring strとそれを操作するAddWorld()メソッドとGetResult()メソッドがある。これで、文字列strにはprivate修飾子がついているので、他のクラスが逆立ちしても直接strの値を操作することができない。これがカプセル化(または隠蔽)というやつか。Cでもグローバル変数を使わず、きっちりとファイルスコープで変数とそれをイジれる関数を管理すればいいんだけどね。メンドイよね。クラスを使うとそれがサクッと出来ちゃう。

これがオブジェクト指向なのか。納得。(*゚∀゚)

C#には他にもインターフェイスやタプルやラムダ式やジェネリックやいろいろな概念が出てきます。一見して難解な概念でもそれはただ学習者を苦しめるためのものではなく、何かしらプログラミングを楽にするためもの。

言語の勉強で行き詰まってしまったら「この概念があるとどんないいことがあるのかな」と考えてみましょう。

で、どこが25行なのかというと、最後のソースhello4.csです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5