Javaの基本はノートを継承し-6-

Javaの基本はノートを継承し-6-

6継承

継承は、クラスの新しいクラスによって作成されたメカニズムが作成されているで継承を使用し、我々は一般的なクラスに応じて共通の一般クラス属性を作成し、特殊な性質を持つ新しいクラスを作成し、新しいクラスは、一般的なクラスの状態や動作を継承しますクラスとサブクラスと呼ばれる彼自身の新しい状態と継承されたクラスの振る舞いのニーズに応じて増加し、親クラスを継承していると呼ばれます。

Javaの、サブクラスは多重継承をサポートしていない親クラスから継承することができます。

継承された1基本的な構文

形式は次のとおりです。

class Student extends People{
    ...
}

キーワードの拡張は、新しいクラスの建設は、既存のクラスから派生していることを示しています。スーパークラス(スーパークラス)と呼ばれる既存のクラス、基底クラス(基底クラス)または親(親クラス);サブクラス(サブクラス)と呼ばれる新しいクラス、派生クラス(派生クラス)または子クラス(子クラス)。スーパークラスとサブクラスは、2人のJavaプログラマは、最も一般的に使用される用語であり、他の言語のプログラマは、より多くの親と子のクラスを使用することを好むことを理解し、これらを継承使用される用語です。サブクラスは、メンバ変数は、このクラスのフルメンバーである必要があり継承します。

相続の同じパッケージ内のサブクラスと親クラス

サブクラスは、デフォルトの継承として親クラスのメンバ変数やメソッド保護され、パブリックアクセスレベルを継承します。

サブクラスとスーパークラスは、同じパッケージに継承されていません

サブクラスは、メンバ変数と親クラスの保護と継承などのパブリックアクセスの方法のみを継承します。


オーバーライド(書き換え)オーバー方法3

サブクラスのメソッドが定義されている場合、その名前、戻り値の型とパラメータ署名が親クラスのメソッドの名前と一致し、戻り型とパラメータ署名一致は、それが親クラスを覆うサブクラスについても方法。

呼がサブクラスでオーバーライドされる同一の戻り型とシグネチャがあり、方法のサブクラスと呼ばれる親クラスとサブカテゴリの方法は、親クラスのメソッドをオーバーライドするクラス階層、でときの方法は、この方法は常に、サブクラスの定義を参照し、親クラスで定義されたメソッドが非表示になります。

ここで注意しなければならない。矛盾がある場合、メソッド・リライトは、場合にのみ、2つの方法の署名と一致し発生し、その後、2つの方法が唯一それをオーバーロードすることができます

オーバーライドメソッドは、制約の多様性を満たさなければならない、以下のことが紹介されました

サブクラス名、署名及びパラメータの戻り型の1方法は、署名と親クラスのメソッドの名前と一致するタイプ・パラメータを返さなければなりません。

public class Base{
    public void method(){
    }
    public class Sub extends Base{
    public int method(){
        return 0;
    }
}

サブクラスは親クラスをオーバーライドする場合は、その後、法律上でオーバーロードされたメソッドを定義します。

2.メソッドは、親クラスをオーバーライドし、アクセス方法が減少することはできません。

親クラスが公開されている場合たとえば、サブクラスは親クラスのメソッドへのアクセスを低減し、この方法は非効率的カバレッジです。コンパイルエラーになります。

3.サブクラスメソッドは、スーパークラスのメソッドよりも多くの例外をスローすることはできません

前記被覆の方法は、同じクラスのサブクラスとスーパーの間に存在するが、オーバーライドされたメソッドをオーバーライドすることはできませんすることができます。

親クラスの静的メソッドは非静的メソッドのサブクラスでオーバーライドすることはできません。

例えば:

public Base{
    public static void method() {
    }
}
public class Sub extends Base {
    public void method(){
    }
}

6.サブクラスは、サブクラスで親クラスの静的メソッドを隠すために、同じ名前の親クラスの静的メソッドと静的メソッドを定義することができます。コンパイル時には、サブクラスで定義された静的メソッドを満たしている必要があり、カバー方法と同様の制約:同じのパラメータ署名方式では、戻り値の同じタイプは、より多くの例外をスローすることができない親クラスのメソッドへのアクセスを減らすことができません。

7. A親クラスの非静的メソッドは、サブクラス静的メソッドによりオーバーライドされません。

親クラスの静的メソッドは非静的メソッドの前にサブクラスでオーバーライドすることはできませんを参照してください。

親クラスの8プライベートメソッドサブクラスがカバーされていません

9.抽象親クラスのメソッドは、2つの方法でカバーするようにサブクラス化することができる:まず、サブクラスは抽象親クラスを実装し、第二の親クラスを再宣言抽象サブクラスです。

たとえば、次のコードは有効です。

public abstract class Base{
    abstract void method1();
    abstract void method2();
}
public abstract class Sub extends Base{
    public void method1() {
    }//实现method1方法,并且扩大访问权限
}
public abstract void method2();//重新申明method2方法,仅仅扩大访问权限,但不实现

10.非抽象親クラスのメソッドが抽象メソッドを覆うことができます。

例えば:

public class Base{
    void method(){
    }
}
public abstract class Sub extends Base{
    public abstract void method();
}//合法

いくつかの注意が書き換え

1.文法のルールを書き換え

サブクラスのインスタンスは、親クラスのメソッドを継承することができる場合、このメソッドはサブクラスは、書き換えする権利を有します。

方法には手段を書き換えます:

親クラスのメソッドの型が「クラス」である場合、サブクラスは、次に、親クラスのサブタイプの種類(いわゆるサブタイプの手段のこのプロセスまたは方法における親クラスのタイプの方法の種類と一致する方法を定義しますこの方法は、オーバーライドタイプのサブクラスである「サブクラス」)が一致していることができ、そしてこの方法の名前、パラメータの数、親クラス及びメソッドの型パラメータと同じ。

このように定義された方法は、サブクラスのサブクラスを書き換えると呼ばれます。

書き換え2.目的

メソッドをオーバーライドすることにより、サブクラスは、サブクラスによって、自分の状態や行動のための親クラスのステータスと動作の変更を上書きすることができ、継承されたメソッドを非表示にすることができます。

親クラスのメソッドが場合はf()、サブクラスによって継承できる子クラスは親クラスのメソッドfをオーバーライドすると、サブクラスは(、)(Fを上書きする権利を持っている)、それは)(継承されたメソッドfを隠し、その後、サブクラスのオブジェクトを呼び出しますメソッドf()はオーバーライドメソッドf()を呼び出さなければなりません。サブクラスがオーバーライドしない場合は、しかし、親クラスのメソッドf()を継承し、オブジェクトを除いて、あなたはF()メソッドを呼び出すことができますコースのサブクラスを作成しましたメソッドf()とのみ、親世代の同じ挙動。

あなたは、サブクラスを使用したい場合は隠されている、継承されたメソッドを呼び出して、継承されたメンバ変数を操作できるメソッドをオーバーライド、あなたも新しいサブクラスのメンバ変数の宣言、新しい定義を呼び出す他の方法を動作しますが、サブクラスによって隠さことができます動作することはできませんメソッドやメンバ変数は、キーワードsuperを使用する必要があります。
例:

class University{
    void enterRule(double math,double english,double chinese){
        double total=math+english+chinese;
        if(total>=200){
            System.out.println("OK");
        else
            System.out.println("No");
        }
    }
}
class ImportantUniversity extend University{
    void enterRule(double math,double english,double chinese){
        double total=math+english+chinese;
        if(total>=245){
            System.out.println("Ok");
        else
            System.out.println("No");
        }
    }
}
public class exercise{
    public static void main(String args[]){
        double math=64,english=76.5,chinese=66;
        ImportantUniversity univer=new ImportantUniversity();
        univer.enterRule(math,english,chinese);
        math=89;
        english=80;
        chinese=86;
        univer=new ImportantUniversity();
        univer.enterRule(math,english,chinese);
    }
}

例:

class A {
    float computer(float x,floaty){
        return x+y;
    }
    public int g(int x,int y){
        return x+y;
    }
}

class B extends A{
    float computer(float x,floaty){
        return x*y;
    }
}
public class exercise{
    public static void main(String args[]){
        B b=new B();
        double result=b.computer(8,9);
        System.out.println("调用重写的方法得到的结果是:"+result);
        int m=b.g(12,8);
        System.out.println("调用继承的方法得到的结果是:"+m);
    }
}

サブクラスがメソッドをオーバーライドした場合でも、次のエラーが発生します。

double computer(float x,float y) {
    return x*y;
}

その理由は、同じ名前のサブクラスで得られ、継承されたメソッドを隠すことができないサブクラスは2つの方法が表示されるように、パラメータが許可されていない、同じである(参照、メソッドサブクラスの種類及びオーバーライド親クラスと矛盾します最後の章VII)


5 superキーワード

5.1スーパー隠されたメンバ変数やメソッドで動作

この方法の場合は、次の場合にブロックされるか、または変数されます。

  • 一つの方法では、ときにクラスのメンバ変数と同じ名前、メンバー変数またはローカル変数と親クラスのローカル変数の場合、同じ名前、可変スコープ規則に従って、ローカル変数のみ見える内部の方法。
  • サブクラスは、親クラスのメソッドをオーバーライドする場合、サブクラスが範囲内にある、親クラスが表示されていません
  • 親子クラスがサブクラスの親クラスのメンバ変数の範囲内で、クラスメンバ変数の名前を定義したときに表示されていません

一度隠されたサブクラスは、メンバ変数を継承し、そのオブジェクトのサブクラス化は、もはやあなたが継承されたメソッドを隠したら、そのサブクラスのオブジェクトを作成することはできません同じサブクラス、スーパーallキーワードによって所有される変数を持っていないだろう隠されたメソッドを呼び出して、この方法は、キーワードsuperを呼び出すための責任があります。

したがって、あなたがキーワードsuperを使用する必要がサブクラスに隠されたキルトクラスのメンバ変数やメソッドを使用したい場合。

class Bank {
    int saveMoney;
    int year;
    double interest;
    public double computerInterest() {
        interest=year*0.035*saveMoney;
        System.out.printf("%d元存在银行%d年的利率是%f元\n",saveMoney,year,interest);
        return interest;
        }
}

class ConstructionBank extends Bank{
    double year;
    public double computerInterest() {
        super.year=(int)year;
        double remainNumber=year-(int)year;
        int day=(int)(remainNumber*1000);
        interest=super.computerInterest()+day*0.0001*saveMoney;
        System.out.printf("%d元存在建设银行%d年%d天的利率是",saveMoney,super.year,day,interest);
        return interest;
    }
}

class BankOfDalian extends Bank{
    double year;
    public double computerInterest() {
        super.year=(int)year;
        double remainNumber=year-(int)year;
        int day=(int)(remainNumber*1000);
        interest=super.computerInterest()+day*0.00012*saveMoney;
        System.out.printf("%d元存在大连银行%d年%d天的利率是",saveMoney,super.year,day,interest);
        return interest;
    }
}

public class exercise{
    public static void main(String args[]) {
        int amount=5000;
        ConstructionBank bank1=new ConstructionBank();
        bank1.saveMoney=amount;
        bank1.year=5.216;
        double interest1=bank1.computerInterest();
        BankOfDalian bank2=new BankOfDalian();
        bank2.saveMoney=amount;
        bank2.year=5.216;
        double interest2=bank2.computerInterest();
        System.out.printf("两个银行利息相差%f元", interest1-interest2);
        
    }
}

結果:

5.2使用スーパーコンストラクタ呼び出し親クラス

まず、サブクラスのコンストラクタは次の構文規則を遵守しなければならない親クラスを呼び出すとき:

  • コンストラクタサブクラスでは、直接ではなく、親クラスのコンストラクタメソッド名で親クラスをコールするが、superステートメントを使用します
  • コンストラクタサブクラスであった場合superステートメント、彼は最初のコンストラクタステートメントを必要として

これは親クラスに指定されていない明白な使用のサブクラスのコンストラクタ場合は、サブクラスのコンストラクタのサブクラスのオブジェクトを作成すると、サブクラスのコンストラクタは、親クラスのコンストラクタを呼び出すために常にある、つまり、コンストラクタは、引数なしの親クラスとサブクラスのコンストラクタと呼ばれています。

サブクラスは親クラスのコンストラクタを継承していないので、したがって、サブクラスは親クラスのコンストラクタを呼び出すために、コンストラクタのスーパーで使用する必要がある、ある、とサブクラス場合スーパーは、すなわち、最初の文のサブクラスのコンストラクタでなければなりません工法、親クラスのコンストラクタを呼び出すためにsuperキーワード有意な書き込みは、デフォルトで以下のとおりです。

super();

例えば:

class Student{
    int number;
    String name;
    Student(){
    }
    Student(int number,String name) {
        this.number=number;
        this.name=name;
        System.out.println("我的名字是:"+name+"学号是:"+number);
    }
}
class UniverStudent extends Student {
    boolean 婚否;
    UniverStudent(int number,String name,boolean b){
        super(number,name);
        婚否=b;
        System.out.println("婚否="+婚否);
    }
}
public class exercise {
    public static void main(String args[]){
        UniverStudent zhang=new UniverStudent(9901,"何晓玲",false);
    }
}

1つ以上のクラスのコンストラクタで定義されている場合、我々はせずに含めなければならない親クラスのコンストラクタを複数定義するとき、そしてJavaは、そのため、デフォルトコンストラクタ(引数なしのコンストラクタ)を提供していません。コンストラクタエラー場合(上記例えば、学生のクラスコード)パラメータのいずれかが、省略超を防止します。

注:まず、スーパークラスのメソッドを呼び出し、そして第二まず、暗黙の参照パラメータ、第二は、他のクラスのコンストラクタを呼び出すことで、等しく、スーパーキーワードは、2つの目的があります。このキーワードは、2つの目的を有していることを思い出してくださいスーパークラスのコンストラクタを呼び出します。あなたはコンストラクタを呼び出すと、これらの二つのキーワードの使用は非常に似ています。最初の文の別のコンストラクタが表示されますのみとコンストラクタステートメントに呼び出します。構成パラメータは、他の構成(本)このクラスに渡すことができ、スーパークラスは、(スーパー)コンストラクタに送信することができます。

場合は、コンストラクタを呼び出すために5.3

さて、このような問題があります:最初に実行される関数の親オブジェクトを作成するとき、コンストラクタまたは親クラス定義のコンストラクタをサブクラスがありますか?答えはクラスの階層で、オーダーのコンストラクタを呼び出すことは、実行するために、親から子クラスにあるにかかわらず、使用、実行サブクラスのコンストラクタの最初のステートメントでなければなりませんスーパー()以来、ということだけではなく、スーパー()、呼び出しシーケンスは同じコンストラクタです。ノースーパー()した場合、デフォルトでは親クラス(不可視の参照)コンストラクタごとに実行されます

class A{
    A(){
        System.out.println("Constructing A.");
    }
}
class B extends A{
    B(){
        System.out.println("Constructing B.");
    }
}
class C extends B{
    C(){
        System.out.println("Constructing C.");
    }
}
class OrderOfConstruction{
    public static void main(String args[]){
        C c=new C();
    }
}

次のようにプログラムの出力は次のようになります。

Constructing A.
Constructing B.
Constructing C.

対象オブジェクトの変換

仮定し、Aは、例えば、親クラス・オブジェクト内のオブジェクトがサブクラスで作成された場合、Bの親であり、オブジェクトへの参照

A a;
a=new B();

または:

A a;
B b=new B();
a=b;

このとき、物体がb型のアップロードの対象オブジェクトであると言います

graph LR
对象-->新增的变量
对象-->新增的方法
对象-->继承或隐藏的变量
对象-->继承或重写的方法
对象的上传型对象-->继承或隐藏的变量
对象的上传型对象-->继承或重写的方法
(いくつかの機能を失って)新しいメソッドのサブクラスと呼ばれることができない。1.アップロード型オブジェクトは、新しいサブクラスのメンバー変数(プロパティのこの部分の損失)を操作することができません。
2.アップロード型のオブジェクトはサブクラスがメンバ変数を継承するか、隠されてアクセスすることができ、あなたはまた、インスタンスメソッドサブクラスは、メソッドまたはサブクラスの書き換えを継承呼び出すことができます。

効果は、これらのメソッドを呼び出すために、サブクラスオブジェクトに相当し、アップロードオブジェクト操作種別サブクラスは、メソッドを継承またはサブクラスは、インスタンスメソッドをオーバーライドします。サブクラスは、親クラスのインスタンスメソッドをオーバーライドする場合したがって、インスタンスメソッドを呼び出す必要があり、オブジェクトタイプのオブジェクトをアップロードするときの書き換えインスタンスメソッドサブクラスを呼び出します。

注意:

1.作成されたアップロードの種類のオブジェクトと親クラスのサブクラスのオブジェクトのオブジェクトを混同しないでください。

2.サブクラスオブジェクトにキャストオブジェクトタイプにオブジェクトをアップロードすることができ、その後、サブクラスのオブジェクトクラスは、すべての属性とサブ機能を持っています。

3.作成した親クラスのオブジェクトで宣言されたサブクラスのオブジェクト参照を割り当てることはできません

class leirenyuan{//类人猿
    void crySpeak(String s){
        System.out.println(s);
    }
}
class People extends Leirenyuan{
    void computer(int a,int b){
        int c=a*b;
        System.out.println(c);
    }
    void crySpeak(String s){
        System.out.println("***"+s+"***");
    }
}
public class exercise{
    public static void main(String args[]){
        Leirenyuan monkey=new People();
        monkey.crySpeak("I love this game");
        People people=(People)monkey;
        people.computer(10,10);
    }
}
//***I love this game***
//100

サルはサブクラスと呼ばれるメソッドをオーバーライドするcrySpeakされているため、これがあることに留意すること。

monkey.computer(10,10);

コンピュータ方法は、新しいメソッドのサブクラスであるので、間違っています。

注意:子クラスが親クラスの静的メソッドをオーバーライドする場合は、オブジェクト型のサブクラスのオブジェクトは、親クラスの静的メソッドを呼び出すことができサブクラスをオーバーライドする静的メソッド呼び出しすることはできませんアップロードします。

サブクラスのコンストラクタのコンストラクタは、superステートメントを持つ親クラスの表示を呼び出すことはありませんが、デフォルトコンストラクタを提供するために、親クラスが存在しない場合は、コンパイルエラーが発生します。


6多状態

次の例では、フィーダーブリーダークラス図、フィード食品、動物動物、およびそのサブクラスを示しています

ブリーダーの動物や食べ物は、独立したサブシステムとみなすことができます。次のように定義されたフィーダークラス:

public class Feeder{
    public void feed(Animals animal,Food food){
        animal.eat(food);
    }
}
Feeder feeder=new Feeder();
Animal animal=new Dog();
Food food=new Bone();
feeder.feed(animal,food);//给狗喂肉骨肉

animal=new Cat();
food=new Fish();
feeder.feed(animal.food);//给猫喂鱼

変数は、動物動物の種類、上記のように定義されているが、実際に犬や猫のインスタンスを指すことができます。目に見える動物の状態が犬になるだろう、猫になり、多くの変数にありますが、これは多型の文字通りの意味です。

Java言語ではなく、参照変数の型への変換、サブクラスのインスタンス変数参照インスタンスへの参照を可能にします。

Animal animal=new Dog();
Dog dog=(Dog)animal;//向下转型,把animal类型转换为Dog类型
Creature creature=animal;//向上转型,把animal类型转换为Creature类型

あなたは、下方への移行と呼ばれるサブクラスの参照変数の型に変換した場合、参照変数変換型の親クラスが上向きに推移となっている場合。変換参照型の変数、様々な制限を受けるだけでなく、それは親クラス属性と物事から継承された参照変数、静的メソッド、インスタンスプロパティ、インスタンスメソッド、および方法によってインスタンスを指す静的プロパティにアクセス中異なる結合メカニズムと、Java仮想マシン。


7継承及び多型(オーバーライドメソッドは、多型をサポートしています)

クラスには、多くのサブクラスを持っており、これらのサブクラスは、親クラスのメソッドをオーバーライドする場合。私たちが作成したオブジェクトが親クラスに配置されたオブジェクトの参照クラスを扱うときに、あなたは、このメソッドを呼び出したときので、それから、アップロード、種々の形態を有することができるオブジェクトタイプをアップロードするオブジェクトの型を取得します別のサブクラスは、親クラスを書き換える時に異なる動作を生成することができます。

class Animal{
    void cry(){
    }
}

class Dog extends Animal(){
    void cry(){
        System.out.println("wangwang");
    }
}
class Cat extends Animal(){
    void cry(){
        System.out.println("miaomiao");
    }
}

public class exercise{
    public static void main(String args{]){
        Animal animal;
        animal=new Dog();
        animal.cry();
        animal=new Cat();
        animal.cry();
    }
}

多型は、サブクラスでオーバーライドされた親クラスのメソッドを指し、それぞれが独自の機能的動作を生成することができます。

抽象指向プログラミング

抽象メソッドの数抽象クラスを宣言することができるシステムを設計する場合、これらの方法は、全体的なシステム設計の重要性を示し、身体の方法によるコンテンツの詳細については、その非抽象サブクラスを完了します。

例えば:

abstract class Geometry{
    public abstract double getArea();
}

柱クラス設計者がジオメトリクラスのコードを書くことができ、そのクラスは、そのメンバーとしてピラージオメトリ・オブジェクトであるべきで、そのメンバーは、オーバーライドジオメトリのサブクラスを呼び出すことができるgetArea()方法をので、柱クラスは底面積を計算するタスクを割り当てることができクラスのサブクラスのインスタンスのための幾何学。

柱のデザインは、もはやつまりオブジェクトクラスの特定のタイプに依存しますが、ジオメトリクラスのために、下の柱である次のクラス次のようにではなく、特定のオブジェクトクラスの宣言よりも、宣言した抽象クラスのジオメトリオブジェクト、柱再設計されたクラスのコードです:

class Pillar{//柱体
    Geometry bottom;
    double height;
    Pillar(Geometry bottom,double height){
        this.bottom=bottom;
        this.height=height;
    }
    public double getVolume() {
        return bottom.getArea()*height;
    }
}

class Circle extends Geometry{//圆底柱体
    double r;
    Circle(double r){
        this.r=r;
    }
    public double getArea() {
        return(3.14*r*r);
    }
}

class Rectangle extends Geometry{//矩形底柱体
    double a,b;
    Rectangle(double a,double b){
        this.a=a;
        this.b=b;
    }
    public double getArea() {
        return a*b;
    }
}

public class exercise{
    public static void main(String args[]) {
        Pillar pillar;
        Geometry bottom;
        bottom=new Rectangle(12,22);
        pillar=new Pillar(bottom,58);
        System.out.println("矩形底柱体的体积是:"+pillar.getVolume());
        bottom=new Circle(10);
        pillar=new Pillar(bottom,58);
        System.out.println("圆底柱体的体积是:"+pillar.getVolume());
    }
}

抽象クラスと、最終的なノートの修飾子は、ノートJavaの基礎-5-Java言語を参照してください

継承の原理を用いたのと長所と短所

  • 階層継承ツリーはあまりありません
  • 抽象化レイヤに上位継承ツリー
  • 最大の弱点の継承:ブレークパッケージ
  • 継承されたクラスのために特別に設計されました
  • 財産と相続の対象を区別

8 Objectクラス

Objectクラスは、Javaのすべてのクラスの祖先である、Javaでの膨張により、すべてのクラスが来ました。しかし、あなたは記述する必要はありません。

public class Employee extends Object;

明示的にスーパークラスに述べられていない場合は、オブジェクトは、スーパークラスであると考えられています。Javaで、すべてのクラスはObjectクラスの拡張機能から派生しているので、そのため、非常に重要なこのクラスで提供されるすべてのサービスに精通しています。この章では、いくつかは、後の章やオンラインドキュメントの言及を見ていない、いくつかの基本的な内容を説明し(、唯一のスレッド、第14章を参照してくださいと呼ばれる処理スレッドのオブジェクトメソッドにはいくつかあります)。

あなたは、Object型の参照オブジェクトの任意の型の変数を使用することができます。

Object obj = new Employee("Harry Hacker", 35000);

もちろん、変数のオブジェクト型は、一般的なホルダーさまざまな値として使用することができます。特定の操作の内容だけでなく、オブジェクトの元の型、および対応する変換タイプをクリアします。

Employee e = (Employee) obj;

Javaでは、基本的な型(プリミティブ型)のオブジェクトではない、例えば、数値、文字、およびブール値はオブジェクトではありません。

それは、オブジェクトや配列の基本型の配列であるかどうかをすべての配列クラスロングバレーは、Objectクラスを拡張してきました。

Employee[] staff = new Employee[10];
obj = staff; // OK
obj = new int[10]; // OK

おすすめ

転載: www.cnblogs.com/whatsabc/p/11489450.html