あどけない話

Internet technologies

オブジェクト指向言語の文法比較

用語の揺れ

まずは用語の揺れから:

僕の用語 インスタンス変数 インスタンス関数 クラス変数 クラス関数
JavaScript インスタンス属性 インスタンス・メソッド クラス属性 クラス・メソッド
Java インスタンス・フィールド インスタンス・メソッド クラス・フィールド クラス・メソッド
C++ メンバー メンバー関数 スタティック・メンバー スタティック・メンバー関数

この他にアクセス制御があります。よく使う二つだけ書くと:

プライベート
そのクラスやインスタンスからしかアクセスできない。var, func(), var, func()
パブリック
他のクラスやインスタンスからアクセスできる。クラス内からアクセするときは、プライベートの表記に同じ。obj.var, obj.func(), Cls.var, Cls.func()

これだけで 4*2 = 8 種類もあるので、とってもややこしいです。

  • インスタンス変数は、プライベートにするのがお勧め
  • パブリックなクラス変数/関数は利用しないのがお勧め
    • これはグローバル変数/関数だから、他のクラスから利用されると、クラス間の結合が強くなってしまう

JavaScript では、クロージャを活用するとプライベートなインスタンス変数は作れますが、一般的ではありません。変数/関数は、すべてパブリックだと思っていいです。僕のJavaScriptスタイルでは、自分がプライベートだと思っている変数/関数の名前は、"_" で始めることにしています。

JavaScript

一般的には:

// コンストラクタ
function Cls(priVar) {
  // 疑似プライベートなインスタンス変数
  this._priVar = priVar;
}
// パブリックなインスタンス関数
Cls.prototype.getPriVar = function() {
};
// 疑似プライベードなインスタンス関数
Cls.prototype._priFunc = function() {
};
// パブリックなクラス変数
Cls.clsPubVar = 5;
// パブリックなクラス関数
Cls.clsPubFunc = function() {
};

prototype.js を使うと:

var Cls = Class.create({
    //コンストラクタ
    initialize: function() {
        // 疑似プライベートなインスタンス変数
	this._priVar = priVar;
    },
    // パブリックなインスタンス関数
    getPriVar = function() {
    },
    // 疑似プライベードなインスタンス関数
    _priFunc = function() {
    }
});
// パブリックなクラス変数
Cls.clsPubVar = 5;
// パブリックなクラス関数
Cls.clsPubFunc = function() {
}

Java

// private と public は省略してはならない
Class Cls {
  public int pubVar;             // インスタンス変数
  public static int clsPubVar;   // クラス変数
  private int priVar;            // インスタンス変数
  private static int clsPriVar;  // クラス変数
  // コンストラクタ
  Cls (x) {
    priVar = x;
  }
  // パブリックなインスタンス関数
  public int pubFunc() {
  }  
  // パブリックなクラス関数
  public static int pubFunc() {
    // this は使えない
    // クラス変数とクラス関数のみ使える
    // main() これにする
  }  
  // プライベートなインスタンス関数
  private int priFunc() {
  }  
  // プライベートなクラス関数
  private static int clsPriFunc() {
    // this は使えない
    // クラス変数とクラス関数のみ使える
  }  
}

C++

// Cls.h
class Cls {
  /* private: */
    int priVar;              // プライベートなインスタンス変数
    static int clsPriVar;    // プライベートなクラス変数
    int priFunc();           // プライベートなインスタンス関数
    static int clsPriFunc(); // プライベートなクラス関数
  public:
    int pubVar;              // パブリックなインスタンス変数
    static int clsPubVar;    // パブリックなクラス変数
    virtual int pubFunc();   // パブリックなインスタンス関数
    static int clsPubFunc(); // パブリックなクラス関数
};
// Cls.cpp
#include "Cls.h"
// パブリックなインスタンス関数
int Cls :: pubFunc () {
}
// プライベートなインスタンス関数
int Cls :: priFunc () {
}
// プライベートなクラス関数
int Cls :: clsPriFunc () {
  // static は付けない
}
// パブリックなクラス関数
int Cls :: clsPubFunc () {
  // static は付けない
}