Javaから始めるC#

この記事はJavaを最低限(初心者向けの参考書程度)理解しており、これからC#を学ぼうとしている方向けのページになります。
C#で最低限のコーディングスキルを学ぶ際の手助けになればと思っています。
※初心者向けの記事なので、厳密には【違いがある】場合でも【同じ】と記載していたりします。
(情報過多を防ぐため)
この記事は以下の目次で記載します。
Javaで開発経験ある場合のC#の学習コストは?
JavaとC#はどちらも同じオブジェクト指向言語です。
基本的にJavaでコーディングできる方はC#のコードも読めます。
Javaの基礎が出来ている方は、C#のコーディング中にググるだけで問題なく開発できます。
よって学習コストは【ほぼ0】です。
※ただし、Windows GUIプログラミングをC#で行なったりするなら話は別ですが。。。
JavaとC#の違い
JavaとC#の違いを羅列するとたくさんあります。
JavaとC#の違い一覧が乗っているサイトを検索したら
『JavaではTrue、Falseを表す型は【Boolean型】だが、
C#ではTrue、Falseを表す型は【Bool型】だ』や
『Javaではクラス、インターフェースの継承方法は【class Cat extends Animal】だが、
C#では【class Cat : Animal】だ』
みたいなことの説明が記載されていたりしました。
このレベルの違いはコーディングしながらその場その場で理解していけば良いことだと思いますので、
今回は、Java経験者がC#の学習を始めるに当たって【個人的に抑えていた方が良いと思う内容】について記載します。
基本的にJava基準で違いを記載していきます。
データ型
Javaのプリミティブ型と違い、C#のデータ型(値型、参照型)は全てObject型から派生しています。
なのでJavaのようにラッパークラスを使わなくても、object型の引数へ直接代入することなどが可能です。
また、全てObject型の派生のためC#では以下のようなことが出来ます。
サンプルコード1
1 2 3 4 5 6 7 8 |
// C# の場合 int num2 = 200; string str2 = num2.ToString(); // Java の場合 int num1 = 100; String str1 = Integer.toString(num1); |
上記のサンプルのようにJavaでは、StaticなtoStringメソッドを呼び出す必要があるが、
C#では、int型の値から直接ToStringメソッドを呼び出すことが出来ます。
この辺はJavaと大きく作りが違うのでC#を学ぶ上であらかじめ理解しておく必要があると思います。
演算子のオーバーロード
C#では演算子のオーバーロードができます。
サンプルコードを見た方が理解しやすいので先にサンプルを載せます。
サンプルコード2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class hoge { public int x { get; private set; } public int y { get; private set; } public hoge(int x, int y) { this.x = x; this.y = y; } public static hoge operator +(hoge a, hoge b) { int x = a.x + b.x; int y = a.y + b.y; return new hoge(x, y); } } |
上記のコードを実際に利用する側のコードが以下になります
サンプルコード3
1 2 3 4 |
hoge a = new hoge(1, 2); hoge b = new hoge(10, 20); hoge c = a + b; // Javaでは出来ないがC#では演算子をオーバーロードすることでhoge型の足し算ができるようになる |
上記、サンプルコードを見た際にJava開発者は数字以外で演算子を利用できるのはString型だけの特権
みたいな認識があると思いますので、C#のコードで出くわしたら驚くのではないでしょうか?
また、演算子のオーバーロードの代表的な例として、
デリゲート(delegate)でのメソッドの参照登録があるのでそちらでも解説します
構造体(Struct)
構造体とは、だいたいクラスと同じようなものと考えて大丈夫です。
実装方法も似ています。
以下、にサンプルコードを記載の上違いを説明します。
サンプルコード4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class hoge { public int x; public int y; public int z; } public struct fuga { public int x; public int y; public int z; } public class MainProgram { hoge hoge = new hoge(); fuga fuga = new fuga(); } |
上記のサンプルプログラムからわかるように実装方法はだいたい同じになります。
では、違いはなに?となるかと思いますが大きな違いは
Classは参照型ですが、structは値型になります。
他にも細かな違い【structは継承に関連する修飾子(abstract
, sealed
, virtual
, override
)が使えない】等の違いはありますが
C#を始めるにあたっては【参照型でなく値型なんだな〜】だけ理解しておけば問題ないです。
値型と参照型の違いは、Javaでも登場するので特に記載する必要はないと思いますので省きます。
構造体(Struct)のまとめ
・Classに似ているけど値型なんだな〜(参照渡しにならないから気をつける。値渡ししたい時に便利)
・インスタンス化した時はヒープでなくスタックに作られる(メモリのことをほとんど気にしなくてすむ)
・値型なので、サイズが小さいものを扱う際はClassを利用するより処理速度が早い
↑結局、値型と参照型の違いなので【Structは値型】と理解しておけば問題ないです!
列挙型(Enum)
Enumに関してはJavaにもあるので一から説明する必要はないと思います。
なぜ、今回Enumを挙げたかというと、
【C#のEnum型はメソッドが定義できない】からです!
Javaでは当然のようにできることなだけにメソッドが定義できないとなると
JavaからC#を始めた方は不便に感じると同時にメソッドが定義できないことに対してびっくりされると思います。。。
じゃあC#でEnumにメソッドを定義したくなったらどうするの?
という話になると思いますが、C#ではEnumにメソッドを定義したい場合は
メソッド拡張を利用します。
拡張メソッドの実装方法は以前別の記事にまとめていましたので、
以下の記事で確認してください。
アクセシビリティ
JavaとC#でアクセシビリティに違いがあります。
初めてC#を触る際に見たことがないアクセシビリティが登場した際はググれば良いと思いますが、
今回、抑えていた方が良いと思った内容はJavaとC#で【defaultのアクセス範囲が違う】点です。
これは、JavaからC#を始めると驚くと思いますので
以下にdefaultを含むアクセシビリティ一覧を表にします。
一番気になるのはクラスのメンバだと思いますのでメンバに関してまとめました。
JavaとC#のクラスメンバのアクセシビリティ一覧
Javaに関しては必要ないかもしれませんが、C#との対比を出すために
Javaに関しても合わせて記載させていただきます。
最初にJavaからです。
Javaのクラスメンバのアクセス範囲一覧
アクセシビリティ | 同一パッケージ | 別パッケージ | |||
---|---|---|---|---|---|
自クラス | 派生クラス | 他クラス | 派生クラス | 他クラス | |
public | ◯ | ◯ | ◯ | ◯ | ◯ |
protected | ◯ | ◯ | ◯ | ◯ | × |
private | ◯ | × | × | × | × |
default | ◯ | ◯ | ◯ | × | × |
次に、C#になります。
C#のクラスメンバのアクセス範囲一覧
アクセシビリティ | 同一アセンブリ | 別アセンブリ |
|||
---|---|---|---|---|---|
自クラス | 派生クラス | 他クラス | 派生クラス | 他クラス | |
public | ◯ | ◯ | ◯ | ◯ | ◯ |
private | ◯ | × | × | × | × |
protected | ◯ | ◯ | × | ◯ | × |
internal | ◯ | ◯ | ◯ | × | × |
internal protected | ◯ | ◯ | ◯ | ◯ | × |
private protected | ◯ | ◯ | × | × | × |
default | ◯ | × | × | × | × |
アクセシビリティまとめ
C#のクラスメンバのdefaultアクセシビリティはPrivateになります。
Javaと違って同アセンブリ内でもアクセスできないので気をつけてね。
C#のクラスメンバ以外のdefaultアクセシビリティに関しては以下の記事にまとめています。
プロパティ(property)
プロパティとは?
Javaでいうところのgetter()、setter()です。
Javaのgetter()、setter()を用いたサンプルコードは今回割愛させていただきます。
Javaのgetter()、setter()はメソッドですが、プロパティはメソッドではありません。
簡単に説明すると、変数みたいに扱える関数です。
説明するよりプログラムを見た方がわかりやすいと思いますので、
以下にサンプルプログラムを記載します。
サンプルコード5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class hoge { private int _x; public int X { get { return _x; } set { _x = value; } } } public class MainProgram { hoge hoge = new hoge(); hoge.X = 10; // setアクセサーが呼び出される 【set { _x = value; } 】 int Y = hoge.X; // getアクセサーが呼び出される 【get { return _x; }】 } |
上記のサンプルを見てわかる通り、Javaのgetter()、setter()を1つにまとめた上で変数みたいな使い方ができるんだな〜
という認識で大丈夫です。
※WPFでプロパティにしないとバインドできないみたいな話もありますが今回はスルーします。
デリゲート(delegate)
C#にはdelegateなるものがあります。
これJavaにはない機能なので別記事にて説明します。
最後に
また、【C#】.Net VerUp内容一覧に知らない機能があればそちらを合わせて理解することをお勧めします。
Javaとは別のアップデートを遂げている機能も多数あります。