私は普段C++を書いているのですが、諸事情で急きょJavaを書くことになりました。そこで、感想がてら簡単な比較を書いてみようと思います。(他の記事よりかなり適当な気持ちで書いてしまった…)
for文
まず、最初に同じ部分から。
どちらの言語も
for (int i = 0; i < size; ++i) {
a[i] = i;
}
が使えます!
型
種類 | C++ | Java |
---|---|---|
論理 | bool | boolean |
文字 | char | char |
整数 | (signed) short, int, long, long long | byte, short, int, long |
浮動小数点数 | float, double, long double | float, double |
- 基本的には似たようなものが多い。
- 論理型のつづりが違う。
- Javaに符号なしの整数はない。
ここで挙げたものはJavaで基本データ型、プリミティブ型などと呼ばれるものです。
これ以外にクラスとして作られているものが大量にあるのですが、それらにはC++とJavaで大きな違いがあります。型の名前を Test とすると、
C++ | Java(基本データ型) | Java(その他のクラス) |
---|---|---|
Test test; |
Test test; |
なし |
Test* test; ,Test& test;
|
なし | Test test; |
のような感じです。Javaにおいて基本データ型でないものは全てアドレスを内部に持つ参照型になります。メンバには test.member
の形式でアクセスする一方、C++の参照とは違って置き換えができたり、Test test = new Test();
のように new で初期化したりとポインタ的な特性も持ちます。
ちなみに、Javaにはdelete
がなく放っておけば自動で消してくれるという便利な仕様があります(shared_ptrみたいに参照回数を数えているのでしょうか?)。
クラスと関数
C++だと
class Test {
private:
double _val;
public:
Test(double val) : _val(val) {}
double get() const { return _val; }
void set(double val) { _val = val; }
};
と書いているものが、Javaだと
public class Test {
private double _val;
Test(double val) {
_val = val;
}
public double get() {
return _val;
}
public void set(double val) {
_val = val;
}
}
// ;は要らない
となります。基本的には似たような気持ちでクラスが作れます。しかし、C++だとクラスはpublicな状態しかないのが、Javaだと何種類か選べます。また、メンバ変数・関数のprivate/publicは各メンバごとに書きます。そして、アクセス指定を書かない状態が意味を持ちます。あとprotectedの意味が違います。クラス内のメンバのアクセス指定は次のような感じです。
指定 | Javaでの意味 | C++での意味 |
---|---|---|
private | クラス内からのみ | クラス内からのみ |
なし | 同じパッケージ内のみ | privateと同じ |
protected | 同じパッケージ内かサブクラスから | クラス内か派生クラス内から |
public | どこからでも | どこからでも |
なお、パッケージはC++の名前空間と似たようなものですが、ディレクトリ構造を使って作る点がC++とは大きく異なる部分だと思います。
継承
C++ だと継承は
class Derived : public Base {
(members)
};
ですが、Javaだと
public class Derived extends Base {
(members)
}
です。基底クラスのアクセス指定はなく、ただ extends Base
と書きます。
メンバーについては virtual
指定とかしなくてもオーバーライド可能です。それを防ぐには final
を使います。
さらに、単なる継承以外に、インターフェースというのもあり、
interface Base {
void func();
}
class Impl implements Base {
void func() {
// implementation
}
}
のように書きます。C++の抽象クラスと似たような印象です。
なお、Javaの派生クラス(サブクラス)の変数は普通に基底クラスの変数へ代入でき、基底クラスの変数から派生クラス側でオーバーロードした関数を呼び出せます(C++の参照と同じ)。
…とこんな感じで色々違いはありつつも基本的なオブジェクト指向のプログラミングはそのままJavaでもできました。リファレンスの本を1冊買うくらいで普通にプログラムが書けて楽しかったです。