1.継承の概念
私たちは以前に学びました:オブジェクト指向の3つの特徴:カプセル化、継承、そしてポリモーフィズム。
継承はポリモーフィズムの前提です。継承がない場合、ポリモーフィズムはありません。
継承によって解決される主な問題は、共通性の抽出です。
いくつかのクラスを書くとき、同じ変数やメソッドがたくさんあります。このように書くと、コードが非常に冗長になります。したがって、これらの共通の変数とメソッドを抽出してクラスに入れ、これらのクラスに継承させることができます。 、したがって、これらの継承されたクラスは、これらの変数とメソッドを記述する必要がなくなり、直接使用できます。また、これらの継承されたクラスは、独自の変数とメソッドを持つことができます。
継承されたクラスは親クラスと呼ばれ、基本クラスおよびスーパークラスとも呼ばれます。
継承されたクラスはサブクラスと呼ばれ、派生クラスとも呼ばれます。
継承関係の特徴:
1.サブクラスは、親クラスの継承可能なコンテンツを持つことができます。
2.サブカテゴリは、新しいコンテンツを自分で転送することもできます。
注:継承関係では、「子クラスは親クラスです」、つまり、子クラスは親クラスとして扱うことができます。
たとえば、親カテゴリは従業員であり、子カテゴリは講師とビショップです。その場合、「講師は従業員です」は「子供は親です」と言うのと同じです。実際、概念と矛盾しないでください。定義の観点からは、すべてのサブクラスは親クラスに属し、コンテンツの観点からは、サブクラスには親クラスが含まれます(反対)。
親クラスの形式を定義します:(一般的なクラス定義)
サブクラスの形式を定義します。
パブリッククラスサブクラス名は親クラス名を拡張します{}
例:親クラス:
public class Employee { public void method(){ System.out.println("方法执行!"); } }
サブクラス:
public class Teacher extends Employee{ }
クラスのサブクラスを呼び出します。
public class Demo04Extends { public static void main(String[] args) { // 没写构造方法的话,编译器送一个 Teacher teacher = new Teacher(); teacher.method(); } }
結果:
つまり、Teacherクラスのオブジェクトを直接インスタンス化して、親クラスのメソッドを呼び出すことができます。
2.親クラスと子クラスの継承関係で、メンバー変数の名前が同じである場合、サブクラスオブジェクトを作成するときにアクセスする方法は2つあります。
1.サブクラスオブジェクトを介してメンバー変数に直接アクセスします。
等号の左側にいる人は誰でも使用されている人を優先し、誰もいない場合は調べます。
public class Fu { int num = 10; }
public class Zi extends Fu{ int num = 20; }
Fu fu = new Fu(); Zi zi = new Zi(); System.out.println(fu.num); // 10 System.out.println(zi.num); // 20
2.メンバーメソッドを介してメンバー変数に間接的にアクセスします。
メソッドに属する人は誰でも使用される人を優先し、そうでない場合は検索します。
public class Fu { int num = 10; public void methodFu(){ // 使用的是本类的,不会向下找 System.out.println(num); } }
public class Zi extends Fu{ int num = 20; public void methodZi(){ // 记住,优先用自己的,如果本类没有该变量,才往父类找 // 即即使注释掉定义num那一行,下面这个输出也不会报错 // 会去父类找到同名的 System.out.println(num); } }
public static void main(String[] args) { Fu fu = new Fu(); Zi zi = new Zi(); System.out.println(fu.num); // 10 System.out.println(zi.num); // 20 zi.methodZi(); // 20 // 这个方法是在父类里定义的,所以这个num是父类的,不会向下找 zi.methodFu(); // 10 }
3.分子法で同じ名前の3つの変数
ローカル変数:直接書き込む
このクラスのメンバー変数:this。メンバー変数名
親クラスのメンバー変数:スーパーメンバー変数名
public class Fu { int num = 10; public void methodFu(){ // 使用的是本类的,不会向下找 System.out.println(num); } }
public class Zi extends Fu{ int num = 20; public void method(){ // 局部变量重名,直接写,出栈即毁 int num = 30; System.out.println(num); // 30,局部变量,优先离得近的 System.out.println(this.num); // 20,成员变量 System.out.println(super.num); // 10,父类的成员变量 } }
public static void main(String[] args) { Zi zi = new Zi(); zi.method(); }
5.継承におけるメンバーメソッドのアクセス特性(親クラスと子クラスのメンバーメソッドの同じ名前に注意してください)
親クラスと子クラスの継承関係では、サブクラスオブジェクトを作成し、メンバーメソッドにアクセスするためのルールは次のとおりです。
オブジェクトを作成した人は誰でも水を優先しますが、そうでない場合は上向きに探します。
予防:
メンバー変数とメンバーメソッドに関係なく、存在しない場合は、親クラスが検索され、子クラスが検索されることはありません。
public class Fu2 { public void methodFu(){ System.out.println("父类方法执行!"); } public void method(){ System.out.println("父类重名方法执行!"); } }
public class Zi2 extends Fu2{ public void methodZi(){ System.out.println("子类方法执行!"); } public void method(){ System.out.println("父类重名方法执行!"); } }
public static void main(String[] args) { Zi2 zi = new Zi2(); zi.methodFu(); zi.methodZi(); zi.method(); }
スクリーンショットを実行します。
6.継承のオーバーライドメソッド(オーバーライド)
概念:継承関係では、メソッド名とパラメータリストは同じです。この場合、書き換えと呼ばれます。メソッドのオーバーロードと区別するように注意してください。
オーバーライド:メソッドの名前は同じであり、パラメーターリストは[同じ]であり、オーバーライドおよびオーバーライドとも呼ばれます。
オーバーロード:メソッドの名前は同じであり、パラメーターリストは[同じではありません]
メソッドカバレッジと書き換えの特性:サブクラスオブジェクトを作成する場合は、サブクラスメソッドが優先されます。
メソッドの適用範囲と書き換えに関する注意事項:
1.親クラスと子クラスの間のメソッドの名前が同じであり、パラメーターリストも同じであることを確認する必要があります。
効果的なオーバーライドを確実に実行するために、メソッドの前に書かれた@Override(アノテーション)を導入して、オーバーライドが有効で正しいかどうかを確認します。エラーがない場合は、上書きします。
このコメントが書かれていなくても、要件を満たしていれば、効果的に上書き・書き換えられ、安全な検出方法にすぎません。
2.サブクラスメソッドの戻り値は、親メソッドの戻り値の範囲以下である必要があります。
小さな前提を思い出してください。Stringクラスには、すべてのクラスに共通の親クラス(基本クラス)である親クラスObjectがあります。
例:親クラスと子クラスの戻り値の型は同じで、正しい形式は次のとおりです。
public class OverrideFu { public Object method(){ Object object = new Object(); return object; } }
public class OverrideZi extends OverrideFu { // 没有报错,即有效重写 @Override public Object method() { Object object = new Object(); return object; } }
親クラスと子クラスの戻り値の型は同じではありません。子クラスの型は親クラスよりも小さいです。正しい形式です。スコープが判断される型は、継承関係のある参照型に限定されることに注意してください。
public class OverrideZi extends OverrideFu { // 没有报错,即有效重写 @Override public String method() { String str = new String(); return str; } }
3.サブクラスメソッドのパーミッションは、親メソッドのパーミッション修飾子以上である必要があります。
小さな拡張機能のヒント:パブリック>保護>(デフォルト)>プライベート
注:(デフォルト)はキーワードdefaultではありませんが、何も記述せず、空白のままにします。
7.継承メソッドのカバレッジと書き換えのアプリケーションシナリオ。
設計原則:使用されているクラスを変更しないようにしてください。共通コンテンツを再読み込みして使用するための新しいクラスを定義し、新しいコンテンツを追加することをお勧めします。
8.継承における工法のアクセス特性
1.サブクラス構築メソッドにはデフォルトの暗黙的な「super()」呼び出しがあるため(記述しない場合、コンパイラーが送信します)、最初に呼び出されるのはスーパークラス構築であり、サブクラス構築である必要があります。それは後で実行されます。
public class Fu3 { public Fu3() { System.out.println("父类构造方法"); } }
public class Zi3 extends Fu3{ public Zi3() { // Super(); //调用父类无参构造方法 System.out.println("子类构造方法"); } }
public class Demo04Constructor { public static void main(String[] args) { // 不仅会用到子类的构造方法,也会用到父类的构造方法 // 且父类的构造方法先调用。 Zi3 zi = new Zi3(); } }
スクリーンショットを実行します。
2.サブクラス構造は、キーワードを使用してスーパークラスオーバーロード構造を呼び出します。
ここでの注意:パラメータなしの構築メソッドを記述せずに、クラスがパラメータ化された構築メソッドをオーバーロードした場合、コンパイラはパラメータなしの構築メソッドを提供しません!
したがって、親クラスの構築メソッドをパラメーターを持つように変更すると、サブクラスはsuper()を書き込みません。呼び出す親クラスのパラメーターなしの構築メソッドがないため、エラーが報告されます。
この時点で、我々はスーパーを使用することができます。()メソッドを呼び出すことで、親クラスのオーバーロードのパラメータ化工法を合わせパラメータ化工法の持つ形式の親クラスのオーバーロード。(この文を色で理解するのは楽観的です)
例えば:
public class Fu3 { public Fu3(int num) { System.out.println("父类构造方法"); } }
public class Zi3 extends Fu3{ public Zi3() { super(3); // 按照格式,写上int参数 // super(); //调用父类无参构造方法 System.out.println("子类构造方法"); } }
3.【要点】super()の親クラス構築呼び出しは、サブクラス構築メソッドの最初のステートメントである必要があり、1つのサブクラス構築に対してスーパー構築を複数回呼び出すことはできません。!!
この文は2つの点に注意を払っています:super()はサブクラス構築メソッドで書かれなければなりません;それは最初の文でなければなりません。
総括する:
サブクラスは親クラスの構築メソッドを呼び出す必要があります。書き込まれない場合はsuper()が指定され、書き込まれる場合は指定されたスーパーが書き込まれた状態で呼び出されます。スーパーは1つのみで、最初のクラスである必要があります。 1。
補足:
1.Java言語は単一継承です。
単一継承:クラスの直接の親は1つだけであり、父親は1つだけです。
2つの親クラスが継承され、2つの親クラスに同じ名前のメソッドがある場合、サブクラスオブジェクトはこのメソッドを呼び出し、コンパイラはどちらを選択するかを決定できません。つまり、コンパイルエラーが発生します。
2. Java言語は、複数のレベルで継承できます。
子クラス(child)には親クラス(parent)があり、親クラスには親クラス(father)があります。
3.サブクラスの直接の親は一意ですが、親は多くのサブクラスを持つことができます。