PythonとJavaのクラス、インスタンス、スコープの違いを比較
Pythonについて少し学んだので、復習を兼ねて忘れないために書き残しておきます。
1. Pythonのクラスは名前空間
クラスとインスタンスに同じ名前の属性を定義し、それぞれに異なる値を設定することができます。 下の例では、Testクラスの中にdata、また _ init _ メソッドの中にもdataという属性を定義しています。Testクラスのインスタンスを作成して呼び出して出力すると、それぞれ異なる値が設定されています。
*クラス内に定義したdefは関数ではなくメソッドと呼ばれ、必ず第1引数に自分のインスタンスself (Javaのthisのようなもの) を指定します。
Python
test.py class Test: data = 'classData' #クラスの属性 def __init__(self, d): self.data = d #インスタンスの属性 def display(self): print self.data, Test.data x = Test(1) x.display()
実行結果:
1 classData
これがJavaだったら、クラス内のdataとコントラクタ内の(this.)dataは同じフィールドを示しているので、どちらも同じ値になります。下の例では、ほぼ同じコードを書くようにして実行してみました。
Java
Main.java class Test { static String data = "classData"; Test(String d) { this.data = d; } void display() { System.out.println(this.data + " " + Test.data); } } class Main { public static void main(String[] args) { Test test = new Test("1"); test.display(); } }
実行結果:
1 1
2. メソッドの呼び出しは2通りある
(1)インスタンス属性へのアクセスする方法と、(2)クラスのメソッドを呼び出す方法があります。クラスのメソッドを呼び出す方法では、インスタンスを引数に渡してあげます。
Python
test.py class Test: data = 'classData' def __init__(self, d): self.data = d def display(self): print self.data, Test.data x = Test(1) x.display() #(1)インスタンス属性へのアクセス y = Test(2) Test.display(y) #(2)クラスのメソッドの呼び出し
実行結果:
1 classData 2 classData
Java
Javaでは、Test.display()のコンパイルを通すには、display()をstaticのクラスメソッドとしなければならないです。(Test.display()とtest.display()を両方実行することはできない。)
3. 演算子のオーバーロード
Pythonでは、演算子のオーバーロードというものがあります。 例えば、 _ sub _ 、 _ add _ のようなメソッドです(フックメソッドというらしい)。
以下のように使います。
Python
class Test : def __init__ (self, d1) : self.data = d1 def __sub__ (self, d2) : return Number(self.data - d2) x = Test(3) y = x - 2 print y.data
実行結果:
1
Java
Javaにはそもそも演算子をオーバーロードする機能がないので、比較は省略。
4. スコープの整理
pythonのスコープは、グローバル、モジュール、クラス、インスタンス、ローカルに分かれています。
Python
x = 'global or module' def a(): x = 'def local' class A: x = 'class' def a(self): x = 'method local' self.x = 'instance' print x #global or module print a() #None print A.x #class obj = A() obj.a() print x #global or module print obj.x #instance print A.x #class
実行結果:
global or module None class global or module instance class
Java
Javaではクラス、インスタンス、ローカルに分かれます。グローバル領域にスコープはなく、モジュールとクラスが同じ領域になると思います。また、クラス変数とインスタンス変数に同じ名前を付けられません。
class Test { static String x = "class"; String y = "instance"; // xをつけるとコンパイルエラー void a() { String x = "local"; this.y = "instance"; } } class Main2 { public static void main(String[] args) { System.out.println(Test.x); Test obj = new Test(); System.out.println(obj.y); obj.a(); System.out.println(Test.x); System.out.println(obj.y); } }
実行結果:
class init instance class call instance
PythonとJavaは同じオブジェクト志向言語でも、Pythonは動的に型を評価するスクリプト言語で、Javaは静的に型を評価するコンパイル型言語なので、かなり異なっている点があると思いました。今後も継続してPythonを勉強していきます。
- 作者: Rubyサポーターズ
- 出版社/メーカー: 技術評論社
- 発売日: 2014/10/31
- メディア: Kindle版
- この商品を含むブログ (1件) を見る