1. ホーム
  2. Java

javaの継承の基本的な実装

2022-02-20 02:01:53
基本実装クラスの継承形式
クラスの継承関係は、javaではextendsキーワードで実現され、次のような形式で動作します。
class 親クラス{}
class subclass extends parent class{}
親クラスの機能を継承し、サブクラスの全機能を拡張する。
class Person{
    private String name;
    private int age;
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
}
class student extends Person{
    // no code is added here
}
public class ExtDemo02{
    public static void main(String args[]){
    Student stu = new Student();
    stu.setName("Zhang San");
    set.setAge(30);
    System.out.println(stu.getName()+stu.getAge());
    }
}














サブクラスは派生クラスと呼ばれることもあります。
継承のさらなる考察
サブクラスのオブジェクトをインスタンス化する処理
サブクラスのオブジェクトをインスタンス化する。
1. 親クラスのコンストラクタを最初に呼び出す -> 親クラスのコンストラクタを呼び出す
2. 次に、子クラスのコンストラクトを呼び出す-> 子クラスのコンストラクトを呼び出す
インスタンスです。
InstanceDemo.java
class Person{
    private String name;
    private int age;
    public Person(){
    System.out.println("Constructor method in parent class Person");
    }
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
}
class Student extends Person{
    private String school;
    public Student(){
    System.out.println("constructed in subclass student");
    }
}
public class InstanceDemo{
    public static void main(String args[]){
    Student stu = new Student();    
    }
}








//出力:親クラス Person で構成
    子クラスStudentでのコンストラクト
実は、この時点でStudentのコンストラクタの1行目には、以下のコードが暗黙のうちに含まれているのです。
    super(); //親クラスのコンストラクタを呼び出します。
つまり、コードに相当するのは
class Person{
    private String name;
    private int age;
    public Person(){
    System.out.println("Constructor method in parent class Person");
    }
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
}
class Student extends Person{
    private String school;
    public Student(){
    super();
    System.out.println("constructed in subclass student");
    }
}
public class InstanceDemo{
    public static void main(String args[]){
    Student stu = new Student();    
    }
}












つまり、サブクラスによってオーバーライドされたメソッドは、親メソッドよりも厳しいアクセス権を持つことはできません。
アクセス権には4つの種類がありますが、ここでは3つについてだけ説明します。
private:クラス内部からのみアクセス可能、最も特権的。
default:何も宣言していないのと同じです。
public:最大限のアクセス
サイズ関係:private<default<public
Personがpublic、Studentがdefaultのように、アクセス権が減少した場合、以下のエラーが発生します。
Student の print() は Person の print() をオーバーライドできないため、弱いアクセス権を割り当てようとしている。
// は、間違った、低い権限を示す
子クラスは自動的にオーバーライドされたメソッドを呼び出しますが、親クラスのメソッドを呼び出す必要がある場合は、この時点で super() キーワードを使用します。
例:Student のコンストラクタ・メソッドは、親クラスのメソッドを次のように変更して呼び出します。
class Person{
    private String name;
    private int age;
    public Person(){
    System.out.println("Constructor method in parent class Person");
    }
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
    public void print(){
    System.out.println("just a moment!");
    }
}
class Student extends Person{
    private String school;
    public Student(){
    super.print();
    System.out.println("constructed in subclass student");
    }
}
public class InstanceDemo{
    public static void main(String args[]){
    Student stu = new Student();    
    }
}














---------------------------------------------------------
質問です。親クラスで private キーワードを使用してメソッドを宣言した場合、子クラスでデフォルトのパーミッションを使用することはオーバーライドとみなされますか?
A:オーバーライドではありません。
------------------------------------------------------
class Person{
    private String name;
    private int age;
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
    private void print(){
    System.out.println("Person------>void print()");
    }
}
class Student extends Person{
    private String school;
    void print(){
    System.out.println("Student-------->void print()");
    }
}
public class InstanceDemo{
    public static void main(String args[]){
    Student stu = new Student();
    stu.print();
    }
}








出力する。学生 ---------->void print()
この時点で、このメソッドはオーバーライドされるのではなく、サブクラスで別の新しいメソッドを再定義するのと同じことになります。
3.3 プロパティのオーバーライド
親クラスの同名のプロパティが、サブクラスで宣言されている。
class Person{
    public String name;
    private int age;
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
    private void print(){
    System.out.println("Person------>void print()");
    }
}
class Student extends Person{
    public String name;
    void print(){
    System.out.println("Attributes in parent class: "+super.info);
    System.out.println("Properties in child class: "+this.info);
    }
}
public class OverrideDemo{
    public static void main(String args[]){
    Student stu = new Student();
    stu.print();
    }
}











3.4 メソッドオーバーライドとメソッドオーバーローディング
オーバーロード オーバーライド
パラメータの型や数が同じメソッド名 パラメータの型が同じで異なるメソッド名 戻り値の型がすべて同じ
パーミッションの要件なし オーバーライドされたメソッドは、より厳しいパーミッションを持つことはできません。
クラスで発生する 継承クラスで発生する
3.5 スーパーキーワード
は、プロパティ、メソッド、コンストラクトなどの呼び出しなど、親クラスで指定された操作がサブクラスから呼び出されることを示します。コンストラクタをパラメータ付きで呼び出したい場合は、superメソッドでパラメータを渡します。
class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
        System.out.println("Parent Ray Person in the constructor ");
    }
    public void setName(String name){
    this.name = name;    
    }
    public void setInt(int age){
    this.age = age;    
    }
    public String getName(){
    return this.name;    
    }
    public int getAge(){
    return this.age;
    }
  }
class Student extends Person{
    private String school;
    public Student(String name,int age,String school){
        super(name,age);
        this.school = school;
        System.out.println("Constructor method in subclass student");
    }
}
public class OverrideDemo{
    public static void main(String args[]){
    Student stu = new Student("Zhang San",30,"Shandong University");
    }
}








子クラスが関与しないコンストラクタ・メソッドを呼び出したとき、関与しないコンストラクタ・メソッドに親が存在しないと、エラーが報告されます。これは、子クラスが関与しないコンストラクタの最初の行で暗黙のうちにスーパーメソッドを呼び出すからです。解決策としては、親クラスに関与しないコンストラクタを定義するか、superを使用してパラメータを持つ親のメソッドを呼び出すことです。
子クラスがインスタンス化されると、まず親クラスのコンストラクタ・メソッドを呼び出しますが、デフォルトでは関与しないコンストラクタを呼び出します。
要約すると
super を使って参照されないメソッドを呼び出す
1. 未修整のコンストラクトを持つクラスを作成します。
2. 親クラスを継承したパラメータなしのコンストラクトを持つサブクラスを作成する。
3. サブクラスでの構築の最初の行にsuperを追加するかしないか
superを使ったパラメータ付きメソッドの呼び出し
1. パラメータ構成を持つクラスを作成します。
2. 親クラスを継承したサブクラスを参照(コンストラクタをオーバーライド)して作成する。
3. サブクラスのコンストラクタの1行目にsuperを追加する(内部パラメータは親コンストラクタと同じ)。
スーパーとの違い
このスーパー
プロパティへのアクセス。このクラスのプロパティにアクセスするか、またはこのクラスにプロパティがない場合は親クラスから見つけます。    プロパティアクセス:親クラスのプロパティにアクセスする
メソッド このクラスのメソッドにアクセスするか、このクラスにメソッドがない場合は親クラスからメソッドを探します。            メソッド。親クラスのメソッドに直接アクセスします。
Construct を呼び出す。このクラスのコンストラクタを呼び出します。コンストラクタ・メソッドの最初の行に配置する必要があります。                コンストラクタを呼び出す。親クラスのコンストラクタを呼び出します。サブクラスのコンストラクタ・メソッドの最初の行に配置する必要があります。
特殊:現在のオブジェクトを示す。                            特殊:そのような概念はない
thisとsuper自身については、どちらもコンストラクタを呼び出すことができ、呼び出される際にはコンストラクタの最初の行に配置する必要があるため、2つのキーワードを同時に出現させることはできません。
質問です。これをコンストラクタ・メソッド(サブクラス)で使用した場合、親クラスのコンストラクタ・メソッドは呼び出されないのでしょうか?

  A: サブクラスで両方の this() メソッドを呼び出すことはできないので、親クラスのコンストラクタ・メソッドがデフォルトで呼び出されることに変わりはありません。