Reusing Classes
6968 ワード
継承時のサブクラスのインスタンスを使用した初期化
サブクラスインスタンスが初期化されると、呼び出し親のコンストラクション関数を表示しない場合、コンパイラは親のデフォルトのコンストラクション関数を呼び出し、この継承チェーンに沿ってObjectまで上へ移動します.子クラスの祖先クラスのコンストラクション関数がパラメータに置き換えられ、パラメータなしも提供されていない場合は、親クラスを呼び出すパラメータ付きコンストラクション関数を子クラスに表示する必要があります.そうしないと、コンパイラはエラーを報告します.
サブクラス内のoverload親のメソッド
Java中性子クラスにおけるoverload親クラスのメソッドは、親クラスのこのメソッド自体にoverloadメソッドがある場合、サブクラスにこれらのメソッドが存在する.C++の親クラスのこれらのoverloadのメソッドにはアクセスできません.
Upcasting
Upcastingとは、親の参照が子のオブジェクトを指します.
finalキーワード
final data
final dataは、次の2つに分類できます.
1.コンパイル時定数public static final double PI=3.14;//ネーミング仕様はすべて大文字、下線で区切られています
2.運転時初期化定数public final int a=new Random(47).nextInt(20);
finalベースタイプを修飾する場合はベースタイプ変数の値は変更できません.オブジェクトの参照を修飾する場合は、参照自体は変更できません.他のインスタンスを指すことはできません.参照が指すオブジェクトの値は変更できます(配列を含む).
Blank finals
blank finalsとは、finalと宣言されたが初期値が付与されていないフィールドを指し、これらのfinalフィールドは使用前に値を付与する必要があり、コンパイラはこれを保証します.これらのblank finalsは、各構造関数で初期化する必要があります.
以上のようにfinalフィールドは、宣言時に初期化されるか、または各構造関数で初期化されるので、fianlフィールドが使用前に必ず初期化されることを保証することができる.
final arguments
finalがベースタイプパラメータを修飾すると、メソッドではこのベースタイプの値を変更できないことを示し、オブジェクト参照を修飾すると、メソッドではこの参照の値を変更できないことを示し、新しいオブジェクトを指すことはできませんが、オブジェクトの値は変更できます.
final method
final methodを使用する理由は2つあります.
1.サブクラスが親クラスのfinal methodをoverrideできない
2.従来、finalプロンプトコンパイラを使用して、あるメソッドをインラインメソッドとして処理していました.後続のjavaバージョンでは、仮想マシンはhotspotテクノロジーを使用して、インライン関数を使用する必要がある状況を自動的に検出し、最適化することができるため、finalプロンプトコンパイラを使用する必要はありません.
privateのメソッドのデフォルトはfinalで、サブクラスのoverride親のprivateメソッドは間違いないように見えますが、実際にはoverrideではありません.サブクラスには親のperivateメソッドが全然見えないからです.
親メソッドに対するoverrideを@Overrideで表すことができます.これにより、overrideでなければ(例えば、子クラスの親privateメソッドの書き換え)エラーが発生します.
final classes
final classesを使用する場合、このクラスが継承されないことを示します.finalクラスのメソッドはfinalキーワード修飾を付けなくてもfinalです.overrideされることは不可能です.finalクラスの属性フィールドはfinalでもなくてもいいです.これは必要に応じて、finalの変更はできません.finalの変更値ではありません.
finalクラスのフィールドもfinalだと思わないでください.それは大間違いです.
ArrayListとVectorの違い
ArrayListのメソッドにはsynchronizedキーワード修飾はありませんが、Vectorには、前者は効率が高く、非スレッドセキュリティ、後者は効率が低く、スレッドセキュリティがあります.前者の使用を提唱し,プログラマが同期論理を制御する.
HashtableとHashMapの違い
Hashtableの方法はsynchronizedキーワード修飾があり,HashMapは存在しないため,前者は効率が低く,スレッドは安全であり,後者は効率が高く,非スレッドは安全である.HashMapのキーと値はnullに許可され、Hashtableはできません.HashTableの代わりにHashMapを使用することを提唱し,同期ロジックはプログラマによって制御される.
初期化とクラスロード
従来の言語(C++)プログラムが1回ロードされ、初期化され、実行が開始されます.
Javaでは、各クラスのclass codeがそれぞれのファイルにあるため、クラスが本当に使用する必要があるときに再ロードおよび初期化できます.すなわち、インスタンスが作成されたり、クラスの静的なフィールドまたはメソッドがアクセスされたりします.
初期化の順序は、静的オブジェクトが初期化されたコードの順序、または静的初期コードブロックの順序に従います.もちろん、静的なものは一度だけ初期化されます.
継承時の初期化順付き
static Insect.x1 initialized static Beetle.x2 initialized Beetle constructor Insect.p initialized i = 9, j = 0 Beetle.k initialized k = 47 j = 39
Beetleを実行すると、その静的mainメソッドにアクセスします.このとき、Beetleクラスはロードされ、ロードが完了すると親がいることがわかります.そのため、最上位レベルまで親をロードします.
次に親クラスのstatic初期化が実行され、次に子クラスのstatic初期化が実行されます.
次にSystem.out.println(「Beetle constructor」)を実行し、そして Beetle b = new Beetle();.
オブジェクトを作成すると、Beetleの組み込みタイプ(継承を含む)がデフォルト値に初期化され、参照タイプがnullに初期化されます.
親クラスの非静的メンバーが初期化され、コンストラクション関数が呼び出され、サブクラスの非静的メンバーが初期化され、サブクラスのコンストラクション関数が呼び出されます.
サブクラスインスタンスが初期化されると、呼び出し親のコンストラクション関数を表示しない場合、コンパイラは親のデフォルトのコンストラクション関数を呼び出し、この継承チェーンに沿ってObjectまで上へ移動します.子クラスの祖先クラスのコンストラクション関数がパラメータに置き換えられ、パラメータなしも提供されていない場合は、親クラスを呼び出すパラメータ付きコンストラクション関数を子クラスに表示する必要があります.そうしないと、コンパイラはエラーを報告します.
public class Test18 {
public static void main(String[] args) {
Cat cat = new Cat();
/×
Animal
Cat
×/
}
}
class Animal{
Animal(){
System.out.println("Animal");
}
}
class Cat extends Animal{
Cat(){
System.out.println("Cat");
}
}
サブクラス内のoverload親のメソッド
Java中性子クラスにおけるoverload親クラスのメソッドは、親クラスのこのメソッド自体にoverloadメソッドがある場合、サブクラスにこれらのメソッドが存在する.C++の親クラスのこれらのoverloadのメソッドにはアクセスできません.
public class Test19 {
public static void main(String[] args) {
Man m = new Man();
m.eat();
m.eat(1);
m.eat(1.2);
m.eat("23");
}
}
class People{
public void eat(){
}
public void eat(int a){
}
public void eat(String b){
}
}
class Man extends People{
public void eat(double d){
}
}
#include <iostream>
using namespace std;
class Father{
public:
void eat(){
}
void eat(int a){
}
};
class Son:public Father{
public:
void eat(double d){
cout<<d<<endl;
}
};
int main(){
Son s;
s.eat(2.3);
s.eat();//wrong
system("pause");
}
Upcasting
Upcastingとは、親の参照が子のオブジェクトを指します.
void test(Father f){}
Son s = new Son();
test(s);//Upcasting
ComponentとInheritenceの間で選択する場合は、Upcastingを使用する必要があるかどうかを判断し、必要であれば継承を使用します.finalキーワード
final data
final dataは、次の2つに分類できます.
1.コンパイル時定数public static final double PI=3.14;//ネーミング仕様はすべて大文字、下線で区切られています
2.運転時初期化定数public final int a=new Random(47).nextInt(20);
finalベースタイプを修飾する場合はベースタイプ変数の値は変更できません.オブジェクトの参照を修飾する場合は、参照自体は変更できません.他のインスタンスを指すことはできません.参照が指すオブジェクトの値は変更できます(配列を含む).
public class Test20 {
public static void main(String[] args) {
// TODO Auto-generated method stub
final Teacher t = new Teacher();
t.age = 10;//right
t = new Teacher();//wrong
}
}
class Teacher{
int age;
}
Blank finals
blank finalsとは、finalと宣言されたが初期値が付与されていないフィールドを指し、これらのfinalフィールドは使用前に値を付与する必要があり、コンパイラはこれを保証します.これらのblank finalsは、各構造関数で初期化する必要があります.
以上のようにfinalフィールドは、宣言時に初期化されるか、または各構造関数で初期化されるので、fianlフィールドが使用前に必ず初期化されることを保証することができる.
final arguments
finalがベースタイプパラメータを修飾すると、メソッドではこのベースタイプの値を変更できないことを示し、オブジェクト参照を修飾すると、メソッドではこの参照の値を変更できないことを示し、新しいオブジェクトを指すことはできませんが、オブジェクトの値は変更できます.
final method
final methodを使用する理由は2つあります.
1.サブクラスが親クラスのfinal methodをoverrideできない
2.従来、finalプロンプトコンパイラを使用して、あるメソッドをインラインメソッドとして処理していました.後続のjavaバージョンでは、仮想マシンはhotspotテクノロジーを使用して、インライン関数を使用する必要がある状況を自動的に検出し、最適化することができるため、finalプロンプトコンパイラを使用する必要はありません.
privateのメソッドのデフォルトはfinalで、サブクラスのoverride親のprivateメソッドは間違いないように見えますが、実際にはoverrideではありません.サブクラスには親のperivateメソッドが全然見えないからです.
public class Test1 {
public final void go(){
System.out.println("Test1 go");
}
}
class SubTest1 extends Test1{
public void go(){//Cannot override the final method from Test1
}
public int go(int i){//correct
return i*i;
}
}
上記コードに示すように、overrideはできませんが、overloadはできます.親メソッドに対するoverrideを@Overrideで表すことができます.これにより、overrideでなければ(例えば、子クラスの親privateメソッドの書き換え)エラーが発生します.
final classes
final classesを使用する場合、このクラスが継承されないことを示します.finalクラスのメソッドはfinalキーワード修飾を付けなくてもfinalです.overrideされることは不可能です.finalクラスの属性フィールドはfinalでもなくてもいいです.これは必要に応じて、finalの変更はできません.finalの変更値ではありません.
finalクラスのフィールドもfinalだと思わないでください.それは大間違いです.
ArrayListとVectorの違い
ArrayListのメソッドにはsynchronizedキーワード修飾はありませんが、Vectorには、前者は効率が高く、非スレッドセキュリティ、後者は効率が低く、スレッドセキュリティがあります.前者の使用を提唱し,プログラマが同期論理を制御する.
HashtableとHashMapの違い
Hashtableの方法はsynchronizedキーワード修飾があり,HashMapは存在しないため,前者は効率が低く,スレッドは安全であり,後者は効率が高く,非スレッドは安全である.HashMapのキーと値はnullに許可され、Hashtableはできません.HashTableの代わりにHashMapを使用することを提唱し,同期ロジックはプログラマによって制御される.
public class Test4 {
public static void main(String args[]){
Hashtable<String,String> hTable = new Hashtable<String,String>();
HashMap<String,String> hMap = new HashMap<String,String>();
//hTable.put(null, "1");
//System.out.println(hTable.get(null));
hMap.put(null, "1");
System.out.println(hMap.get(null));
}
}
上記のコードに示すように、Hashtableキーがnullの場合、コンパイルにエラーは発生しませんが、実行時にポインターエラーが報告されます.HashMapは楽でストレスがありません.Hashtableは下手なので、HashMapで代用しなければならないと言えます.初期化とクラスロード
従来の言語(C++)プログラムが1回ロードされ、初期化され、実行が開始されます.
Javaでは、各クラスのclass codeがそれぞれのファイルにあるため、クラスが本当に使用する必要があるときに再ロードおよび初期化できます.すなわち、インスタンスが作成されたり、クラスの静的なフィールドまたはメソッドがアクセスされたりします.
初期化の順序は、静的オブジェクトが初期化されたコードの順序、または静的初期コードブロックの順序に従います.もちろん、静的なものは一度だけ初期化されます.
継承時の初期化順付き
class Insect {
private int i = 9;
protected int j;
Insect() {
System.out.println("i = " + i + ", j = " + j);
j = 39;
}
private int p=print(" Insect.p initialized");
private static int x1 =print("static Insect.x1 initialized");
static int print(String s) {
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = print("Beetle.k initialized");
public Beetle() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}
private static void dd()
{
System.out.println("dd ");
}
private static int x2 =
print("static Beetle.x2 initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle();
}
}
プログラム出力:static Insect.x1 initialized static Beetle.x2 initialized Beetle constructor Insect.p initialized i = 9, j = 0 Beetle.k initialized k = 47 j = 39
Beetleを実行すると、その静的mainメソッドにアクセスします.このとき、Beetleクラスはロードされ、ロードが完了すると親がいることがわかります.そのため、最上位レベルまで親をロードします.
次に親クラスのstatic初期化が実行され、次に子クラスのstatic初期化が実行されます.
次にSystem.out.println(「Beetle constructor」)を実行し、そして Beetle b = new Beetle();.
オブジェクトを作成すると、Beetleの組み込みタイプ(継承を含む)がデフォルト値に初期化され、参照タイプがnullに初期化されます.
親クラスの非静的メンバーが初期化され、コンストラクション関数が呼び出され、サブクラスの非静的メンバーが初期化され、サブクラスのコンストラクション関数が呼び出されます.