先にまとめ
Javaでは、クラスのメンバにアクセス修飾子を付けない場合、パッケージアクセスになります。
一方で、C#でクラス(及び構造体の)メンバーにアクセス修飾子を付けない場合は、privateになります。C#の場合、privateを付けても省略しても同じなので、個人的には省略した方がいいと思います。
また、Javaのインターフェースは、publicとabstract修飾子を付けることが可能です。ですが、インターフェースですからそれらがついて当たり前ですし、わざわざ書くのは冗長ですね。publicもabstractも書かない方がいいと思います。また、定数を定義することもできます。
一方C#のインターフェースでは、abstractもpublicも書けません。コンパイルエラーになります。そして、定数は定義できません。インターフェースはC#の仕様の方が好きです。
JavaとC#、クラスメンバのアクセスレベルを省略すると
protectedの違いは把握していたのに、省略時の違いに気づけるまでちょっと間が空いてしまいました。
Javaでクラスメンバのアクセス修飾子を省略すると...
Javaの場合、クラスのメンバに対してアクセス修飾子を省略すると、そのメンバは同じパッケージからアクセスする事が可能です。
本来はprivateアクセス修飾子をつけた方がいい場合でも、テストの為にアクセス修飾子をつけず、パッケージアクセスにする場合もありますね。
Guava(Google製の便利ライブラリ)には、privateのアクセスなどが望ましいメンバに対して、テストの為にそれよりも広いアクセスレベルを指定している場合などを示すためのアノテーション、VisibleForTestingアノテーションがありますね。
参考:Controlling Access to Members of a Class(Java Tutorials)
C#でクラス(と構造体)メンバのアクセス修飾子を省略すると...
では、C#ではどうでしょう。
C#でクラスのメンバに対して、アクセス修飾子を省略した場合、privateになります。
privateになります。
同一名前空間からアクセス可能とかではありません。
同一アセンブリからアクセス可能とかではありません。
privateになります。
参考:MSDN アクセシビリティ レベル
参考:C# 5.0の言語仕様ダウンロードページ
こちらのブログさんでもとても分かりやすく解説されています。
情報科学屋さんを目指す人のメモというブログ[C#のアクセス修飾子を書かなかった場合に関して]
省略しても書いてもprivateならば、書かなくていいと思う
省略してもprivate、書いてもprivateならば、書かない方がいいと思います。皆さんはどう思いますか?
ただ、私自身のC#関連の投稿で
ばっちりprivateって書いていますね。今後書く時は、書かないようにします。
JavaとC#でprotectedの意味が違うことは、早い段階で把握していたのだけれども、なぜかこのアクセス修飾子を省いた際については抜けてしまいました。(Javaのprotectedは自クラスと同一パッケージとサブクラス、C#のprotectedは自クラスとサブクラスのみ)お恥ずかしい。
蛇足ですが、これに気づいたのはだいたい半年くらい前にUnityのNGUIというアセット(ライブラリ)のコードを見て気づきました。「これなんで、privateアクセス修飾子書いてないんだって」って気づいて、調べたら書かないとprivateになると気づくという。
私はUnityのゲーム開発でC#を書いているのですが、UnityでのC#もやはりprivateは書かなくていいかなって思います。
Unityはプログラマー以外にも、デザイナーさん、プランナーさんなどがコードを触る機会が多くあります。そのような方には、プログラマーから「publicと書けばインスペクターに表示されたり、他のクラスから見えるようになる」と伝えればいいかと思います。こういう場合private、こういう場合publicよりは、覚えやすいかと。
Scalaだと
Scalaだとクラスメンバーのアクセス修飾子のデフォルトでpublicみたいです。そしてpublicという予約語が無いようです。
つまり何も書かなきゃpublicだし、publicにしたいなら何も書かないとするしかない。というより、書くと怒られる。
いいですね!
C#の場合、private修飾子を付けることが可能なのがクラスと構造体のメンバだけで、 クラスメンバも構造体のメンバも、アクセス修飾子が省略された場合にprivateになる。だったら、『privateという予約語は無く、privateアクセスにしたいならば、何も書かないようにする』とかだったらいいのにな、と思いました。C#ができた時、そうしなかったのは、もしかしたら歴史的な経緯があるのでしょうか?
Javaに似せたとか?J++???
http://csharptan.wordpress.com/2011/12/01/c%E3%81%A3%EF%BC%81/
JavaとC#のインターフェースの違い
さて、今回の記事を書こうと思ったきっかけになったインターフェースの違いです。
Javaのインターフェース
さて話は戻って、Javaのインターフェースです。
メソッドに冗長な修飾子を付けられる
インターフェース、メソッドの実装はできませんね。
宣言したメソッドは、当然publicでabstractですよね。
さて、ここで宣言したメソッドは当然publicでabstractなのですが、その修飾子をわざわざ付けることができます。下記のリンク先では、「It is permitted, but discouraged」とありました。
参考:Java 7の言語仕様 インターフェース 9.4.Abstract Method Declarations
うーん、書けてしまうのがあまり好きではありません。
個人的にも、無駄な修飾子を書かないし、書いてほしくないです。
定数も宣言できる
Javaのインターフェースはpublic static finalな変数が定義できます。
staticインポートが無かった時、『クラス名.クラス変数名
でアクセスするのが冗長なので、定数を定義したインターフェースを作り、それを実装することでクラス変数名
だけでアクセスできる。』というTipsが昔あったというのを、目にした記憶があります。『定数のインターフェース型の変数に、その定数インターフェースを利用したクラスのインスタンスを代入できたりするし、そもそも定数群をまとめたクラスがよくないよね〜』というのも、目にした記憶があります。
参考:Java 7の言語仕様 インターフェース 9.3. Field (Constant) Declarations
また、定数を定義する際もpubic、static、final書かなくても良いですし、書いても良いようです。
一方でC#のインターフェースは?
C#のインターフェースです。
C#のインターフェイスには、メソッド、プロパティ、イベント、そしてインデクサーを宣言できます。
定数の定義はできないです。
当然宣言したメソッドなどは、public abstract
扱いです。
そして、public
、abstract
を書いたらコンパイルエラーになるようです。
話それますが、C#ってJavaほどインターフェース書きませんよね?
Javaの場合。コールバック用にインターフェースを定義。引数でインターフェースを実装した匿名クラスを渡す。または、コールバックを受けたいクラスが、そのインターフェースを実装する。ということを良くしますよね。(Java8より前です。)
だけれどもC#の場合、コールバックとして、デリゲートを引数として渡すように設計しますよね。実際の呼び出す時も、ラムダ式とか、メソッドグループ変換とかを使うと思います。
Javaと比べてC#でインターフェースを書く機会はかなり少ないのかと思います。
C#のインターフェースの方が好きです。
はい。インターフェースはC#の方が好きです。
あまり書く機会多くないですが。
まとめ(再掲)
Javaでは、クラスのメンバにアクセス修飾を付けない場合、パッケージアクセスになります。
一方で、C#でクラス(及び構造体の)メンバーにアクセス修飾子を付けない場合は、privateになります。C#の場合、privateを付けても省略しても同じなので、個人的には省略した方がいいと思います。
また、Javaのインターフェースは、publicとabstract修飾子を付けることが可能です。ですが、インターフェースですからそれらがついて当たり前ですし、無駄ですね。publicもabstractも書かない方がいいと思います。また、定数を定義することもできます。
一方C#のインターフェースでは、abstractもpublicも書けません。コンパイルエラーになります。そして、定数は定義できません。インターフェースはC#の仕様の方が好きです。