Java の設計者は C++ の複雑さを嫌うため、Java は非常に簡潔であり、GC によってメモリ管理も非常に便利になります。C# は Java の GC および仮想マシン テクノロジに興味を持っており、いくつかの主要な Microsoft 言語を .NET に統合することを望んでいます。 。 したがって、C# は言語的には単純ではなく、複雑ですらありません。
2 つの言語の設計思想も異なります。Java はコンパイルされて解釈される言語ですが、C# はコンパイルされてから実行される言語です。 Java にはデリゲートがありませんが、C# にはデリゲートがあります。 Java ではインターフェイスを使用してデリゲート関数を実装する傾向がありますが、C# では抽象クラスがインターフェイスよりも大きな役割を果たします。
Java は Camel 命名規則に従い、C# は Pascal 命名規則に従います。しかし現在、ますます多くの Java ユーザーが C# を使用し始めており、同時に C# に Camel の命名規則を導入しているため、C# コードがますます読みにくくなっている可能性があります。そもそもなぜ C# は Camel に従わなかったのでしょうか? ラクダの命名規則には何の問題もありません。
1. クラス名.thisと内部クラス
Java では、クラス名.this というような使い方がよくありますが、なぜその前にクラス名が来るのでしょうか。 C# プログラマーはこれに混乱するでしょう。
Javaでは内部クラスがいろいろなところで使われており、内部クラスで外部クラスのメンバにアクセスすることもできるのですが、このとき内部クラスでこれを使うと、これは何なのか、何なのかという疑問が生じます。それは内部クラスの現在のオブジェクト インスタンスですか、それとも外部クラスの現在のオブジェクト インスタンスですか?
Javaでは、この前に外部クラスのクラス名を追加することで、外部クラスの現在のオブジェクトインスタンスが内部クラスで使用されることを意味します。
以下に例を見てみましょう。
//外部クラス定義
パブリッククラスOuterClass{
//内部クラス定義
プライベートクラス InnerClass
{
// 内部クラスには id メンバーが定義されていません。ここでは外部クラスのメンバーにアクセスします。
public int getId(){ アウタークラス.this.id を返す }
public void setId(int id) {OuterClass.this.id = id;}
// name メンバーは内部クラスで定義されており、デフォルトでは、内部クラスのメンバーに直接アクセスされます。
プライベート文字列名。
public String getName() { return this.name;}
// この前に内部クラスの名前を追加できます
public void setName(String name) { InnerClass.this.name = 名前;}
// 内部クラスは外部クラス内の同じ名前のメンバーにもアクセスできるため、外部クラスの名前を追加する必要があります。
public String getOuterName() { 戻り値OuterClass.this.name;}
public void setOuterName(String name) {OuterClass.this.name = 名前;}
@オーバーライド
パブリック String toString()
{
return "ID: " + this.getId() + "、内部名: " + this.getName() + "、外部名: " + this.getOuterName();
}
}
//外部クラスで定義されたメンバーIDと名前
プライベート int ID;
プライベート文字列名。
プライベート InnerClass innerInstance;
パブリックOuterClass()
{
this.innerInstance = 新しい InnerClass();
this.innerInstance.setId(20);
this.innerInstance.setName("トム");
this.innerInstance.setOuterName("アリス");
}
パブリック String toString()
{
this.innerInstance.toString() を返します。
}
}
C# では、クラスは入れ子になったクラスと入れ子になっていないクラスに分けられます。前者は他のデータ型の内部で宣言されたクラスです。後者は、特定の名前空間で直接定義されたクラスです。入れ子になったクラスが C# で定義されることはほとんどありません。
非埋め込みクラスでは、パブリックおよび内部アクセス制御の使用のみが許可されますが、組み込みクラスでは、プライベート、プロテクト、内部保護、パブリックおよび内部の 5 つのアクセス制御文字すべての使用が許可されます。内部クラスは、インスタンス メソッドやプライベート メソッドを含む外部クラスのすべてのメソッドにアクセスすることもできますが、外部クラスのインスタンスを明示的に渡す必要があります。
C# の内部クラスは、外部クラスで定義された型や静的メソッドを使用できますが、外部クラスのインスタンス メソッドを直接使用することはできないため、上記の問題は存在しません。
C# では、外部クラスは内部クラスの名前空間のように機能します。アクセス制御が許可されている限り、次のメソッドを使用して内部クラス オブジェクトのインスタンスを作成できます。
innerClass.InnerClass obj = new innerClass.InnerClass(); このインスタンスは、外部クラスのインスタンスと直接の関係はありません。 Java の静的内部クラスに似ています。
2. クラス名.クラスと種類
Java では、クラス名.class の使用法がよく見られます。この使用法は、型の型オブジェクト インスタンス参照を取得するために使用される、C# の typeof (クラス名) に相当します。
Java では、各クラスに対応する Class オブジェクトがあり、クラスを作成してコンパイルすると、クラスの型情報を表す Class オブジェクトが生成された .class ファイル内に生成されます。クラス インスタンスを取得する 3 つの方法:
オブジェクト インスタンスの getClass() メソッドを呼び出して、オブジェクトの Class インスタンスを取得します。
Class の静的メソッド forName() を使用して、クラスの名前を使用して Class インスタンスを取得します。 Class.forName(xxx.xx.xx) はクラスを返します。その機能は、指定されたクラスを検索してロードするように JVM に要求することです。これは、JVM がクラスの静的コード セグメントを実行することを意味します。
クラス名 .calss を使用して Class インスタンスを取得します。基本データ型のカプセル化クラスの場合、.TYPE を使用して、対応する基本データ型の Class インスタンスを取得することもできます。
C# で型オブジェクトのインスタンスを取得する方法は、より簡単かつ明確です。
データ インスタンスの GetType() メソッドを呼び出すことで取得されます。このメソッドは Object から継承されるため、C# のすべてのオブジェクトには GetType() メソッド x.GetType() があります (x は変数名)。
typeof(x) の x は、特定のクラス名、型名などでなければならず、変数名にすることはできません。
System.Type の静的メソッド System.Type.GetType() を通じて。
3. 匿名クラス
Java では、匿名クラスもよく使用されます。たとえば、Android では、ボタンの監視を実装するときに、このようなコードがよく見られます。
@オーバーライド
public void onClick(View arg0) {
インテントテント = new Intent(MainActivity.this, ActivityFrameLayout.class);
setTitle("フレームレイアウト");
startActivity( 意図 );
}
};
ここで、OnClickListenter は実際にはインターフェイスです。このインターフェイスをオブジェクト インスタンスの作成に使用できますか?もちろん違います。
したがって、Java は、ここでインターフェイスを実装する匿名クラスを自動的に作成します。実際に作成するのは、この匿名クラスのオブジェクト インスタンスです。
この利点は、一度だけ使用されるクラスを定義し、このクラスを通じてオブジェクト インスタンスを作成する必要がなくなり、プログラム開発が簡素化されることです。
たとえば、次のようなインターフェイスがあります。
instance.onClick(); C# では、この形式はまったく使用しません。委任によって、同じ機能を非常に簡単に実現できます。
Java にはデリゲートがないことに注意してください。
このインスタンスの型を出力すると、この匿名クラスの実際の型が表示されます。
属性の概念は誰にとっても馴染みがあるはずです。クラス メンバー関数は、このクラス内の任意の属性メンバーに自由にアクセスできます。ただし、あるクラスから別のクラスのプロパティにアクセスするのはさらに面倒なので、Getxxx メソッドや Setxxx メソッドを使用することが多くなりますが、これは非常に不自然に見えます。たとえば、Java や C++ では、コードは次のようになります。
ただし、C# では、そのようなメソッドは「属性付き」です。同じコードを C# では次のようになります。
foo.size++;
label.font.bold = true;
ご覧のとおり、C# の方が明らかに読みやすく、理解しやすいです。この「プロパティ メソッド」のサブルーチン コードからも同様の状況がわかります。
Java/C++:
C#:
このような属性付きメソッドをクラスの属性メンバーと区別するために、C# では属性メンバーを「フィールド」と呼び、「属性」はこの「属性付きメソッド」の特別名詞になります。ちなみに、この種の属性メソッドは、VB や DELPHI ではよく見かけますが、VB ではアトリビュートとも呼ばれます。さらに、C# では Get と Set はペアで指定する必要があります。プロパティには Set なしで Get のみを含めることはできません (Java および C++ では、Get のみまたは Set のみを含めることができます)。これを C# で行う利点は、これを行うのが簡単であることです。特定の属性を変更するときに、同時に Get メソッドと Set メソッドに注意を払い、同時に変更することはありません。
5. オブジェクトのインデックス作成メカニズム (Indexer)
オブジェクトのインデックス作成メカニズムは C# に導入されました。より明確に言うと、オブジェクト インデックスは実際にはオブジェクトの配列です。前のセクションのプロパティに関連して説明します。プロパティでは Get メソッドと Set メソッドを非表示にする必要がありますが、インデックス メカニズムでは各オブジェクトの Get メソッドまたは Set メソッドが公開されます。たとえば、次の例はこの点をより明確に示しています。上記では、C# と Java の違いを紹介しました。
ストーリー [インデックス] = 値;
}
}
}
...
}
以上、C#とJAVAの違いを紹介しましたが、C#とJAVAの理解に役立てていただければ幸いです。