Java C# JavaScript のクラスの違いを比較する

# Java C# JavaScript のクラスの違いを比較する

## はじめに

最近 Java を軽く学習したり、JavaScript の開発業務をやったりしてクラスにいろいろ触れてきたので、アウトプットを兼ねて 3 種類の言語のクラスについて比較していきます。クラスとは何か、オブジェクト指向とは何かという概念的な話は今回は触れません。

## 念のためクラスとは
とはいえ、軽くは触れておきます。
Wikipedia を参考に簡単にいうと「クラスとは、オブジェクト指向に登場する概念のこと。オブジェクトを生成するための設計図あるいはひな形に相当するもの」です。

## クラスの作り方

まずはクラスの作り方から比較していきます。

### コード

C#

```C#
class TestClass
{
 //クラスの中身
}
```

Java

```java
class TestClass
{
 // クラスの中身
}
```

JavaScript

```javascript
class TestClass {
  // クラスの中身
}

// クラス式
let TestClassF = class {
  // クラスの中身
};
```

### 解説

クラスの作り方自体は基本すべて同じです。クラス宣言をして、クラス名、{}を記載して中身を書いていくという流れになります。ただし、JavaScript だけはクラス式として定義することも可能です。クラス式は再定義が可能となります。

## メンバー変数の書き方

次にメンバー変数とメソッドの書き方です。
C#

```C#
class TestClass
{
    // メンバー変数
    string testMember = "testmember";
}
```

Java

```java
class TestClass
{
    // メンバー変数
    String testMember = "testmember";
}
```

JavaScript

```javascript
class TestClass {
  // メンバー変数
  constructor(testMember) {
    this.testMember = testMember;
  }
}
```

### 解説

Java と C#はほぼ同じ書き方ができます。JavaScript は他言語のようにクラス内に直接メンバー変数を定義することはできません。コンストラクターを使って定義する必要があります。

## メソッドの書き方

### コード

C#

```C#
class TestClass
{
    // メンバー変数
    string testMember = "testmember";

    // メソッド引数戻り値なし
    void testMethod()
    {
        Console.WriteLine(testMember);
    }

    // メソッド引数アリ
    void testMethodA(string testArg)
    {
        Console.WriteLine(testArg);
    }

    // メソッド戻り値アリ
    string testMethodR()
    {
        return testMember;
    }
}
```

Java

```java
class TestClass
{
    // メンバー変数
    String testMember = "testmember";

    // メソッド引数戻り値なし
    void testMethod()
    {
        System.out.println(testMember);
    }

    // メソッド引数アリ
    void testMethodA(String testArg)
    {
        System.out.println(testArg);
    }

    // メソッド戻り値アリ
    String testMethodR()
    {
        return testMember;
    }
}
```

JavaScript

```javascript
class TestClass {
    // メンバー変数
    constructor(testMember) {
        this.testMember = testMember;
    }
    // メソッド引数戻り値なし
    testMethod(){
        console.log(this.test)
    }

    // メソッド引数アリ
    testMethodA(testArg){
        console.log(testArg)
    }

    // メソッド戻り値アリ
    testMethodR(){
        return this.testMember;
    }
}
```

### 解説

基本的な書き方はほぼ同じです。JS のみ、戻り値の指定がなかったり引数に型宣言が不要だったりと自由度が高いです。

## コンストラクタの書き方

C#

```C#
class TestClass
{
    // メンバー変数
    string testMember;

    // コンストラクタ
    public TestClass(string testMember)
    {
        this.testMember = testMember;
    }

    // メソッド引数戻り値なし
    void testMethod()
    {
        Console.WriteLine(testMember);
    }

    // メソッド引数アリ
    void testMethodA(string testArg)
    {
        Console.WriteLine(testArg);
    }

    // メソッド戻り値アリ
    string testMethodR()
    {
        return testMember;
    }
}
```

Java

```java
class TestClass
{
    // メンバー変数
    String testMember;

        // コンストラクタ
    public TestClass(String testMember)
    {
        this.testMember = testMember;
    }

    // メソッド引数戻り値なし
    void testMethod()
    {
        System.out.println(testMember);
    }

    // メソッド引数アリ
    void testMethodA(String testArg)
    {
        System.out.println(testArg);
    }

    // メソッド戻り値アリ
    String testMethodR()
    {
        return testMember;
    }
}
```

JavaScript

```javascript
class TestClass {
    // メンバー変数兼コンストラクタ
    constructor(testMember) {
        this.testMember = testMember;
    }
    // メソッド引数戻り値なし
    testMethod(){
        console.log(this.test)
    }

    // メソッド引数アリ
    testMethodA(testArg){
        console.log(testArg)
    }

    // メソッド戻り値アリ
    testMethodR(){
        return this.testMember;
    }
}
```

### 解説

JavaScript はメンバー変数も兼ねているので変化なしです。Java と C#は全く同じ書き方ですね。

## カプセル化

C#

```C#
class TestClass
{
    // メンバー変数
    string testMember;

    // コンストラクタ
    public TestClass(string testMember)
    {
        this.testMember = testMember;
    }

    // カプセル化
    string TestCapsule {get; set;}

    // メソッド引数戻り値なし
    void testMethod()
    {
        Console.WriteLine(testMember);
    }

    // メソッド引数アリ
    void testMethodA(string testArg)
    {
        Console.WriteLine(testArg);
    }

    // メソッド戻り値アリ
    string testMethodR()
    {
        return testMember;
    }
}
```

Java

```java
class TestClass
{
    // メンバー変数
    String testMember;
    private String testCapsule;

        // コンストラクタ
    public TestClass(String testMember)
    {
        this.testMember = testMember;
    }

    // カプセル化
    void SetCapsule(String testCapsule)
    {
        this.testCapsule = testCapsule;
    };

    String GetCapsule()
    {
        return this.testCapsule;
    };

    // メソッド引数戻り値なし
    void testMethod()
    {
        System.out.println(testMember);
    }

    // メソッド引数アリ
    void testMethodA(String testArg)
    {
        System.out.println(testArg);
    }

    // メソッド戻り値アリ
    String testMethodR()
    {
        return testMember;
    }
}
```

JavaScript

```javascript
class TestClass {
    // メンバー変数兼コンストラクタ
    constructor(testMember, testCapsule) {
        this.testMember = testMember;
        this.testCapsule = testCapsule;
    }

    // カプセル化
    set TestCapsule( value ) {
        this.testCapsule = value;
    }

    // ゲッターメソッド
    get TestCapsule() {
        return this.testCapsule;
    }

    // メソッド引数戻り値なし
    testMethod(){
        console.log(this.test)
    }

    // メソッド引数アリ
    testMethodA(testArg){
        console.log(testArg)
    }

    // メソッド戻り値アリ
    testMethodR(){
        return this.testMember;
    }
}
```
### 解説
C#やJavaScriptにはプロパティという強力な機能があるのでカプセル化を非常に簡単に実装することができます。ただしJavaScrip側はメンバー変数がコンストラクタで設定しなければならないのであまり多くのプロパティを実装することはおススメできません。  
一方Javaにはプロパティ機能がないため、メンバー変数毎にGet/Setメソッドを作成してあげる必要があります。

## まとめ
3つの言語のクラスについてまとめました。こうして見比べてみるとそれぞれ長所短所が見えてきますね。次は継承やポリモーフィズムについて見比べてみたいです。