継承と統合の基本概念
継承:既存のクラスに基づいて新しいクラスを構築できます。既存のクラスを継承すると、これらのクラスのメソッドとドメインを再利用できます。これに基づいて、クラスの機能を拡張するために新しい方法とドメインを追加できます。
合成:新しいクラスで元のオブジェクトを作成することは、合成と呼ばれます。これにより、フォームを変更せずに既存のコードを再利用できます。
1。継承された構文
キーワードの拡張は、新しいクラスが既存のクラスから派生していることを示します。既存のクラスは親クラスまたはベースクラスと呼ばれ、新しいクラスはサブクラスまたは派生クラスと呼ばれます。例えば:
クラスの学生は人を拡張します{}クラスの学生は人を継承します。人クラスは親クラスまたはベースクラスと呼ばれ、学生クラスはサブクラスまたは派生クラスと呼ばれます。
2。合成の合成
合成は比較的単純です。これは、クラスに既存のクラスを作成することです。
クラスの学生{犬の犬;}上向きのスタイリング
1。基本概念
継承の役割は、コードの再利用にあります。継承とは、親クラスのすべての方法をサブクラスでも使用できることを意味するため、親クラスに送信されるメッセージを派生クラスに送信することもできます。 PersonクラスにEATメソッドがある場合、学生クラスにはこの方法があります。つまり、学生オブジェクトは人物の一種でもあります。
class person {public void eat(){system.out.println( "eat");} static void show(person p){p.eat();}} public class destuent extends person {public static void main(string [] args){student s = new Student(); person.show(s); //【操作結果】:
食べる
直接定義されたショー方法は、人のハンドルを受信するために使用されますが、①では学生オブジェクトへの参照を受け取ります。これは、学生オブジェクトが人物でもあるためです。 showメソッドでは、渡されたハンドル(オブジェクトへの参照)は、人オブジェクトと派生したクラスオブジェクトです。学生ハンドルをパーソンハンドルに変換するこの動作は、上向きのパターンになります。
2。なぜ形をトレースする必要があるのですか?
イートを呼び出すときにそれを呼び出すオブジェクトタイプを意図的に無視したいのはなぜですか?ショーメソッドを作成すると、学生のハンドルを取得するだけで、より直感的で理解しやすいように見えますが、それは人クラスから派生したすべての新しいクラスが独自のショー方法を実装するようにします。
class value {private int count = 1; private value(int count){this.count = count;} public static final value v1 = new value(1)、v2 = new値(2)、v3 = new値(3);} class eat(value v){system.out.println( "person.eat() {system.out.println( "teacher.eat()");}} class Student extends person {public void eat(value.out.println( "sustent.eat()");}} public castingdemo {public static void show(sustent(sudent.vane)(s.eat.v1);} public static void show) {T.eat(value.v1);} public static void show(person p){p.eat(value.v1);} public static void main(string [] args){sustent s = new deuster(); new Teacher(); pers p = new person(s); show(t); show(p);}}}}このアプローチの明らかな欠陥は、各個人クラスのデリバティブクラスに密接に関連するメソッドを定義し、多くの重複コードを定義する必要があることです。一方、メソッドの過負荷を忘れた場合、エラーを報告しません。上記の例の3つの表示方法は、1つにマージできます。
public static void show(person p){p.eat(value.v1);}動的バインディング
ショーを実行するとき、出力の結果はStudent.eat()です。これは確かに望ましい結果ですが、私たちが望んだ形で実行されていないようです。ショー方法をもう一度見てみましょう。
public static void show(person p){p.eat(value.v1);}それは人のハンドルを受け取ります。ショーを実行するとき、その人が教師オブジェクトの代わりに生徒のオブジェクトを指していることをどのようにして知っていますか?コンパイラにはそれを知る方法はありません。これには、次に説明する拘束力のある問題が含まれます。
1。メソッドコールバインディング
メソッドと同じメソッド本体を一緒に接続することは、結合と呼ばれます。実行前にバインディングが行われた場合、「初期結合」と呼ばれます。上記の例では、1人のハンドルのみがある場合、コンパイラはどの方法を呼び出すかを知りません。 Javaは、操作中にオブジェクトのタイプを決定し、対応するメソッドを呼び出すことができるメソニズムを呼び出すメカニズムを実装します。オブジェクトのタイプに基づくこの結合は、動作中の動的結合と呼ばれます。方法が最終と宣言されていない限り、Javaのすべてのメソッドは動的に結合されます。
画像を使用して、上向きの形状の相続関係を表します。
コードでは、次のように要約されています。
Shapes=newShape();
継承関係によれば、Circleは形状に属しているため、作成されたCircleオブジェクトハンドルを形状に割り当てることは合法です。
基本的なクラスのメソッドの1つが呼び出される場合:
Shapes=newShape();
この時点で、Circle.Draw()が呼び出されます。これは動的結合によるものです。
class person {void eat(){} void speak(){}} class boy extends person {void eat(){system.out.println( "boy.eat()");} void speak(){system.out.println( "boy.speak()");}} class extends person {system.out.println( "girl.eat()");}} public class persons {public static person randperson(){switch((int)((int))(math.random() * 2)){default:case 0:return new boy(); case 1:return new girl();}} public void main(int int) <p.length; /+){p [i] = randperson(); // boyまたはgirl} for(int i = 0; i <p.length; i ++){p [i] .eat();}}}人から派生したすべてのクラスについて、人は一般的なインターフェイスを確立し、すべての派生クラスには2つの行動があります。派生クラスはこれらの定義を無効にし、両方の動作を再定義します。メインクラスでは、RandPersonは人オブジェクトのハンドルをランダムに選択します。 **アピールスタイルは、returnステートメントで発生します。 ** returnステートメントは、男の子または女の子のハンドルを取り、それを人のタイプとして返します。現時点では、それがどんなタイプなのかわかりませんが、それが人物のハンドルであることしか知っていません。主な方法では、RandPersonメソッドを呼び出して、人オブジェクトを配列に記入しますが、特定の状況はわかりません。配列の各要素のEATメソッドが呼び出される場合、動的結合の関数は、オブジェクトの再定義された方法を実行することです。
ただし、動的結合は前提条件であり、バインディング方法は基本クラスに存在する必要があります。そうしないと、コンパイルされて渡されません。
class person {void eat(){system.out.println( "person.eat()");}} class boy extends person {void eat(){system.out.println( "boy.eat()");} void speak(){system.out.println( "boy.speak(" boy.speak(); {person p = new boy(); p.eat(); p.speak(); //メソッドspeak()はタイプの人のために定義されていません}}}サブクラスでオーバーライドメソッドが定義されていない場合、親クラスのメソッドは次のように呼ばれます。
class person {void eat(){system.out.println( "person.eat()");}} class boy extends public class persons {public static void main(string [] args){person p = new boy(); p.eat();}}}}【操作結果】:
person.eat()
2。静的法の結合
上記の方法に静的キーワードを追加し、それらを静的メソッドに変換します。
class person {static void eat(){system.out.println( "person.eat()");} static void speak(){system.out.println( "person.speak()");}} class boy extends person {system.out.println( "boy.speak()");}} class girl extends person {static void eat(){system.out.println( "girl.eat()");} static void speak(){system.out.println( "girl.speak()");}} public class class persons {public sittic rand(){public Static Randperson ((int)(math.random() * 2)){default:case 0:return new boy(); case 1:return new girl();}} public static void main(string [] p = new person [4]; for(int i = 0; i <p.length; i ++){p [i] = randperson(i> for for for(pis); p.length; i ++){p [i] .eat(}}} 【操作結果】:
person.eat()
person.eat()
person.eat()
person.eat()
観察結果:静的方法については、親クラスが言及するサブクラスオブジェクトに関係なく、親クラスの方法が呼び出されます。
ニーモニック式
- 静的方法:静的メソッド親クラスを調べます
- 非静的な方法:非静的な方法サブクラスを見てください
要約します
上記は、Java相続の概念に関するこの記事の詳細な解釈のすべての内容であり、誰にとっても役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!