Javaのクラスとオブジェクトの基本

クラスとオブジェクト

クラス、関係、およびオブジェクト参照

クラスとオブジェクト間の関係

  • クラスはテンプレートオブジェクトは、オブジェクトクラスのインスタンスである、クラスには、多くのオブジェクトを持つことができます
  • 同じクラスのJavaプログラムは、同じ名前のタイプではないだけで1つのクラス名を持つことができます
  • オブジェクトは、クラスから作成することができます

参照とオブジェクトクラスとの関係

  • リファレンスは、それがクラスの種類を属するオブジェクトを指すことができます
  • あなたは間の割り当ての同じ型を参照することができます
  • 唯一のそのようなメンバ変数のアクセスとして、オブジェクトの操作へのオブジェクト参照を指し示すことにより

方法

パラメータの受け渡し

Javaは、常に使用する値でコールを

値転送の基本的な種類
public class PrimitiveTransferTest {
    public static void swap(int a, int b) {
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("swap 方法里 a 的值为: " + a + " b的值为: " + b);
    }

    public static void main(String[] args) {
        int a = 6;
        int b = 9;
        swap(a, b);
        System.out.println("交换结束后 a 的值为 " + a + " b的值为 " + b);
    }
}

/**
运行结果:
swap 方法里 a 的值为: 9 b的值为: 6
交换结束后 a 的值为 6 b的值为 9
*/

分析チャート:

常にJavaのプログラム()メソッドは、主から実行され、main()メソッドは、2つのローカル変数、スタック領域内の2つの主な変数bを、定義します。main()メソッドのスワップ()メソッドを呼び出すときに、この時点でメイン()メソッドが終了していない、システムはメインメソッド二スワップスタック領域を分配する方法、およびローカル変数はプロセスをスワップ記憶するための主な方法です。パラメータとして渡されたメインメソッドA、B法スワップ変数は、実際には、スワップ領域のB法スタック、およびmainメソッドスタック領域は、変数の値は、Bが割り当てられている2つの変数が再生されます(初期化される)メソッドスワップスタック領域A、Bパラメータ。この場合、システムメモリに、二つの変数、二つの変数bを、存在する異なる方法は、スタック領域に存在します。

伝送パラメータのリファレンスタイプ
public class ReferenceTransferTest {
    public static void swap(DataWrap dw) {
        int tmp = dw.a;
        dw.a = dw.b;
        dw.b = tmp;
        System.out.println("swap 方法里, a 成员变量的的值为: " + dw.a + " b 成员变量的值为: " + dw.b);
    }

    public static void main(String[] args) {
        DataWrap dw = new DataWrap();
        dw.a = 6;
        dw.b = 9;
        swap(dw);
        System.out.println("交换结束后, a 成员变量的的值为: " + dw.a + " b 成员变量的值为: " + dw.b);
    }
}

/**
swap 方法里, a 成员变量的的值为: 9 b 成员变量的值为: 6
交换结束后, a 成员变量的的值为: 9 b 成员变量的值为: 6
*/

あなたのメンバ変数オブジェクトDW値ことを疑うことができる転写のこの基本的なタイプの前面が完全に異なっていると、Bは、置換されています。これは、着信スワップ方法はDWオブジェクト自体ではなく、そのレプリカで、感じることは非常に簡単です。実際には、転送がまだDW値です。

分析チャート:

DWシステムのコピーとして割り当てが、キーは単に参照変数DWであり、その値は単にメモリアドレスた記憶、メモリアドレスがスタック領域を交換するために送信され、DW、DWのこの時点で、スタック領域スワップのメインスタック領域値は、セグメントDataWrapオブジェクトヒープメモリへのメモリアドレス点同じメモリアドレスです。DataWrap操作の対象となるスワップスタック領域上DW操作。

オーバーロード

過負荷:同じクラス、同じメソッド名、異なるパラメータリスト。

呼び出し元のメソッドがオーバーロードされている場合は、メソッドが呼び出されるパラメータの数と型が正確に一致する方法を決定し、過負荷が実行されます。

コンストラクタ

デフォルトの引数なしのコンストラクタ

クラスには、任意のコンストラクタを定義しない場合にのみ、システムはデフォルトのコンストラクタを提供します。この設定は、すべてのインスタンスフィールドは、デフォルト値に設定されます。

カスタムビルダー

カスタムクラスのコンストラクタがある場合、システムはデフォルトコンストラクタを提供することはありません

静的定数

public static final double PI = 3.1415926

staticメソッド

クラスがそこにロードされた場合、および任意のクラスの任意のインスタンスに依存しません。

代わりに、一例として、オブジェクトを呼び出すので、概念を混同することは非常に容易になり、クラス名、呼び出し元が推奨。

受け継ぎます

Javaの使用は、それが延びて面白いです意味の拡張である、キーワードとして継承を拡張し、継承されません。しかし、うまく拡張し、親と子のクラスの関係を反映して、サブクラスは親クラスの拡張である、サブクラスは親の特別な種類です。より正確に拡張します。PS:この理解は本当にああ虐待されています。

サブクラスのオーバーライド継承されたメソッド(カバー)

ルール「大きな二つの小さなを持つ2つの」続く書き換える方法:

  • 同じメソッドの名前、同じパラメータリスト

  • バリュー型サブクラスのメソッドは、戻り値の型は親クラスのメソッド以下にする必要があります返す、親クラスのクラス投げるメソッドまたは同等より小さくなければならない例外がスローされたメソッドサブクラス宣言されたクラスの例外

  • サブクラスのメソッドへのアクセスは、親クラスのメソッド以上のアクセスであるべきです

この方法は、親クラスがサブクラスを覆われていると呼ばれています

  • この方法は、例の方法、superキーワードの使用によって覆われている場合
  • メソッドは、クラスメソッドで覆われている場合は、親クラスは、クラス名を使用して
  • サブクラスは変更され、親クラスのプライベートメソッドとプロパティを呼び出すことはできません。

サブクラスは親クラスのコンストラクタを呼び出します

  • サブクラスは、親クラスのコンストラクタを継承することはできません。サブクラスのコンストラクタでは、スーパー親クラスのコンストラクタを使用していない明示的に呼び出す場合、システムは、サブクラスのコンストラクタ、引数なしで暗黙の呼び出し親クラスのコンストラクタを実行する前

  • サブクラスのコンストラクタで明示的に親クラスのコンストラクタを呼び出してスーパーに使用することができるが、superステートメントは、最初の行でなければなりません

ポリモーフィズム

型変換アップ

Javaの参照変数の2種類があります。矛盾のコンパイル時と実行時の型の種類が多型を発生することがあります。

  • コンパイル時の型:変数が宣言されたときに使用されるタイプによって決まります

  • ランタイムタイプ:実際に変数に割り当てられたオブジェクトによって決定

サンプルコード:

public class BaseClass {
    public int book = 6;

    public void base() {
        System.out.println("父类的普通方法");
    }

    public void test() {
        System.out.println("父类的test方法");
    }
}

public class SubClass extends BaseClass {
    public String book = "轻量级 Java EE";

    public void test() {
        System.out.println("子类的test方法");
    }

    public void sub() {
        System.out.println("子类的sub方法");
    }

    public static void main(String[] args) {
        BaseClass ploymophicBc = new SubClass();
        System.out.println(ploymophicBc.book);
        ploymophicBc.base();
        ploymophicBc.test();
        // 因为 ploymophicBc 的编译时类型是 BaseClass
        // BaseClass 类没有提供 sub 方法,所以下面代码编译时会出错
        // ploymophicBc.sub();
    }
}

上記の例では、ploymophicBc特殊参照変数は、それがタイプタイムコンパイル基底クラスであり、実行時の型は、サブクラスです。

ploymophicBc.sub()コンパイル時エラーでこのコード行、ploymophicBc BaseClassの時間タイプをコンパイルし、サブBaseClassの方法が定義されていないので、時間をコンパイルすることができないからです。

注意は、しかし、ploymophicBc.bookは6ではなく"軽量のJava EE"です。ので、オブジェクトのインスタンス変数が多型を持っていない、システムは常に、それはむしろ実行しているよりも、型定義をコンパイルするメンバ変数にアクセスしようとします。

サブクラスは、実際にこのようにアップキャスト(アップキャスト)と呼ばれるサブクラスに親Javaクラス・オブジェクトへの参照を可能にする特別な親クラスは、アップキャストは、システムによって自動的に行わ。

どのような方法は、それが参照型に依存します(コンパイル)、呼び出すことができます。
オブジェクトインスタンス(ランタイム)の基準点に応じた固有のメソッド呼び出し、。

愁い

質問:コンパイル時にコード内の参照変数は、それが唯一の方法のコンパイル時の型で呼び出すことができますが、それは実行時の型とメソッドを呼び出すことはできません

解決策:実行時の型にキャスト

方法:型の間の基準変換は、2つのだけの継承の種類があり、またはコンパイラエラーの間とすることができます。あなたは親クラスの参照変数のコンパイル時にクラス型のサブタイプに変換したい場合は、その変数のこの参照実行時の型は、サブクラス型である必要があり、そうでない場合ClassCastException

サンプルコード:

//创建子类对象  
Dog dog = new Dog();  
  
// 向上类型转换(类型自动提升),不存在风险  
Animal animal = dog;  
  
// 风险演示 animal 指向 Dog 类型对象,没有办法转化成 Cat 对象,编译阶段不会报错,但是运行会报错
Cat cat = (Cat)animal; // 1.编译时按 Cat 类型  2. 运行时 Dog 类型,类型不匹配,直接报错  

instanceofは

キャストを解決するためには、instanceof演算子導入異常ClassCastExceptionが発生につながる可能性があります。

instanceof演算子を意味する:(実際の実行時の型又はジャンルと呼ばれる)オブジェクトの左側を決定する手段と、クラスまたは右のサブクラス、クラスのインスタンスです。それはそうでない場合はfalse、trueを返す場合。

コードの前に、instanceofを判断し使用する前にキャストします。

if (anmial instanceof Cat) {
    Cat cat = (Cat)animal;
}

final修飾子

クラスの最終修正

それは継承できません

最終的修飾法

サブクラスの対象ではありません

変数の最終修正

特長:変数が初期化されると、それを変更することはできません

初期化:直接割り当ての定義、コンストラクタで

その値は不変である基本的なタイプのフィールドについて。

参照型の変数が関係しているために、それだけで一つの基準を救いました。最終的には、これだけ変数によって参照されるアドレスが変化しないことを確実にするために、それは同じオブジェクトへの参照でした。しかし、オブジェクト自体の内容を変更することができます。

Objectクラス

オブジェクトを出力するための自己記述情報をTOSTRING。

toString Objectクラスは、オブジェクトの実装クラス「クラス名+ @ +ハッシュコード」のリターンを提供します。通常は、このメソッドをオーバーライドする必要があります。

==

変数値の基本的なタイプは、限り、2つの変数が(データ型が同じではない)等しいように、それは真を返します。

2つの参照型変数の場合、彼らは同じオブジェクトを指しているときにのみ、裁判官== trueを返します。

等しいです

メソッドがインスタンスメソッドオブジェクトのクラスであると等しいです。参照変数の場合は、同じオブジェクトにあれば真と点のみを返します。一般的には、equalsメソッドをオーバーライドする必要があります。

例のオーバーライドメソッドに等しいです。

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj !=null && obj.getClass() == Person.class) {
            Person personObj = (Person)obj;
            if (this.getIdStr().equals(personObj.getIdStr())) {
                return true;
            }
        }
        return false;
    }

等しいがtrueの場合、ハッシュコードは、一般的に知られている仕様は、合意された、等しくなければなりません。それがtrueに等しいことは同じハッシュコードの完全非必要な条件です。

インターフェース

デザインのアイデア

  • インターフェース仕様は設計思想及び分離を具現化、構成要素間のカップリングのためのインターフェースは、ソフトウェア・システムが疎結合設計であることができ

  • インタフェース定義複数の外側チャネルと通信している一般的なクラスの一般的な動作の仕様は、通常、それはインタフェースがパブリックメソッドのセットを定義することを意味しています

定義

  • 修飾子インターフェース、唯一の公共またはデフォルト

  • インタフェースは仕様によって定義されているので、それはコンストラクタと初期化ブロックの定義を含むことができないインターフェースは、静的な定数、方法(のみ抽象メソッド、クラスメソッド及びデフォルト)、および内部クラス、内部インターフェイス、内部の部品を含みます動き

  • インターフェイスは、静的定数で唯一の定数であり、公共の静的な最終修正をデフォルト

  • 内部クラスのインタフェース、内部インタフェース、内部列挙、変更デフォルトのpublic staticを使用して

  • 抽象メソッドのインタフェースは、メソッド本体を持つことはできませんが、クラスおよびデフォルトのメソッドは、メソッド本体を持っている必要があります。

メソッド説明

インタフェース抽象的なキーワードで定義された抽象メソッドを省略して修飾することができる、デフォルトの修飾子はpublicです。

Javaの8の新しいインターフェイスは、デフォルトの変更を使用して、デフォルトのメソッドを定義することができます。デフォルトでは、システムが変更され、デフォルトのパブリックメソッドを使用しています。

Javaの8新しいプライベートメソッドは、インターフェイスを定義することができます。

Javaの新しい8は、インターフェイスの静的メソッドを定義することができます。静的クラス・インタフェース・メソッドは継承を実装することができます。

使用

クラスは、1つまたは複数のインターフェイスを実装することができます。

クラスが実装されるすべての抽象クラスインターフェースのメソッドを書き換えなければならない、1つ以上のインターフェースを実装します。それ以外の場合は、クラスは抽象クラスとして定義する必要があり、インターフェイスは、親からの抽象メソッドの予約を継承します。

インタフェースは、インスタンスを作成するために使用できませんが、参照型の変数を宣言するために使用することができ、変数は、クラスインターフェースのオブジェクトのインスタンスを達成するために指していなければなりません。

抽象クラス

抽象クラスと普通のクラス間の違いは、のように要約することができる「トレードオフ。」

あまりにも、より抽象クラスの能力を指し、抽象クラスの抽象メソッドを含めることができます

損失は​​抽象クラスへの能力の喪失を意味し、抽象クラスはインスタンスを作成するために使用することはできません

抽象クラスと通常のクラスの違い:

  • 抽象クラスは、抽象修正を使用しています

  • 抽象クラスとメンバ変数、メソッド、コンストラクタ、初期化ブロック、インナークラスとして、一般的なカテゴリを含み得ることができます。しかし、それは抽象クラスで、主に使用される抽象クラスのコンストラクタ呼び出しをインスタンス化することはできませんサブクラス化

  • 抽象クラスは、抽象メソッドを含んでいないかもしれませんが、抽象クラスはメソッドが抽象クラスとして定義する必要があります含まれてい

抽象的デザインのアイデア:抽象クラスは、テンプレートパターンの設計パターンが反映されます。抽象クラスは、抽象化のより高いレベルを有する、特定のクラスの複数の親クラスから抽象化されます。抽象の複数の同じクラスを持つことは、抽象クラス、抽象クラスのサブクラス用のテンプレート、ランダム性を回避するように設計されたサブクラスが特徴

内部クラス

内部クラスのメンバー

非静的な内部クラス
public class Cow {
    private double weight;

    public Cow() {
    }

    public Cow(double weight) {
        this.weight = weight;
    }
    // 定义一个非静态内部类
    private class CowLeg {
        private double length;
        private String color;

        public CowLeg() {}
        public CowLeg(double length, String color) {
            this.length = length;
            this.color = color;
        }
        public double getLength() {
            return this.length;
        }
        public void setLength(double length) {
            this.length = length;
        }
        public String getColor() {
            return this.color;
        }
        public void setColor(String color) {
            this.color = color;
        }
        public void info() {
            System.out.println("当前牛腿的颜色是 " + this.color + ", 长 " + this.length);
            // 直接访问外部类的 private 修饰的成员变量
            System.out.println("该牛腿所属的奶牛重: " + weight);
        }
    }

    public void test() {
        CowLeg cl = new CowLeg(1.12, "黑白相间");
        cl.info();
    }
    public static void main(String[] args) {
        Cow cow = new Cow(378.9);
        cow.test();
    }
}

非静的内部クラスで直接内部非静的内部クラスのオブジェクトであるため、外側のクラスのプライベートメンバにアクセスそれが参照するオブジェクトの外部寄生クラスを保存することができます。図は次のとおりです。

クラスメンバ変数外部ローカル変数であれば、同じ名前の内部クラスメソッドとクラス内のメンバ変数

  • ローカル変数への直接アクセス

  • この、内部クラスのインスタンス変数へのアクセス

  • 外部クラスのクラス名.this.varNameアクセス外部クラスのインスタンス変数

クラスの外部メンバーが直接非静的内部クラスに関係なく、修飾子が変更するものの非static内部クラスのメンバーにアクセスすることはできません。唯一の非静的な内部クラスのオブジェクトは、そのインスタンスのメンバにアクセスするために作成されて表示されます。

静的な内部クラス(クラスの内部クラス)

修飾された静的内部クラスを使用している場合、この内部クラスは、クラス外部オブジェクトのクラス自体ではなく、一部の外部に属します。そこで、クラス内部クラスと呼ばれます。その静的内部クラスは、クラス外部の静的メンバです。

静的な内部クラスは、静的メンバを含むことができ、また、非静的メンバが含まれていてもよいです。

外側のクラスのインスタンスメンバーにアクセスすることができない静的な内部クラスは、クラスのメンバーは、クラス外部からアクセスすることができます。

あなたはまた、静的な内部クラスのインスタンスにアクセスするには、発信者として、静的な内部クラスのオブジェクトを使用することができ、外部のクラスはまだ直接メンバーstaticな内部クラスにアクセスすることはできませんが、クラスメンバー静的な内部クラスにアクセスするには、発信者としてのクラス名に静的内部クラスを使用することができますメンバー。

内部クラスのクラスへの外部からのアクセスに加え、

(静的および非静的含む、二つ)の外側のクラスの外の内部クラスへのローカルアクセス、内部クラスは、プライベート修正を使用できない、修飾されたプライベート内部クラスは、外部クラス内で使用することができます。他のクラスの内部アクセス修飾子、修飾アクセスのためのフィールドが及びます。

  • アクセス指定子省略内部クラスは、外部のクラスと同じパッケージ内の他のクラスによってアクセスすることができます

  • 保護された修飾された内部クラスを使用して、サブクラスは外部クラス外の他のクラスとクラスにアクセスするために、同じパッケージ内にあってもよいです

  • 内部クラスは、どこからでもアクセスできる公開修飾子を使用します

外側のクラス外の非静的内部クラス

オブジェクトが非static内部クラスのオブジェクトを作成する前に、あなたが最初にその外部オブジェクトを作成する必要があり、クラス外のオブジェクト内寄生虫の非static内部クラスでなければなりませんので。

サンプルコード、次のように:

public class Out {
    // 使用默认访问控制符,同一个包中的其他类可以访问该内部类
    class In {
        public In(String msg) {
            System.out.println(msg);
        }
    }
}
public class CreateInnerInstance {
    public static void main(String[] args) {
        Out.In in = new Out().new In("Test Msg");
        /*
        上面代码可以改为如下三行代码
        使用 OutterClass.InnerClass 的形式定义内部类变量
        Out.In in;
        创建外部类实例,非静态内部类实例将寄生在该实例中
        Out out = new Out();
        通过外部类实例和new来调用内部类构造器创建非静态内部类实例
        in = out.new In("Test Msg");
        */
    }
}

以下に、サブクラスがアウト非静的内部クラスのクラスのクラスで継承定義します

public class SubClass extends Out.In{
    // 显示定义 SubClass 的构造器
    public SubClass(Out out){
        out.super("hello");
    }
}

上記の奇妙なコードを見えるかもしれませんが、実際には、非常に正常である:非静的内部クラスクラスのコンストラクタでは、スーパークラスでコンストラクタを呼び出し、アウト外部のオブジェクトを表すコードに代わって、呼び出すために外部のオブジェクトを使用する必要があります。

あなたはサブクラスのオブジェクトを作成する必要がある場合は、アウトオブジェクトを作成する必要があります。オブジェクト内の非静的内部クラスのサブクラスにおいてサブクラス非静的内部クラスは、オブジェクト・アウトへの参照が存在しなければならないので、サブクラスのサブクラスは、オブジェクト・アウトを参照してオブジェクトを保持すべきです。オブジェクトは、対応する基準物点アウトサブクラスで作成オブジェクトはオブジェクトアウトサブクラスコンストラクタに渡されます。

サブクラスオブジェクトコードでは、非静的内部クラスの上記2枚を組み合わせて、オブジェクトが外部オブジェクトへの参照点を持っている必要があり、あなたがオブジェクトの2種類を作成するとアウト着信さまざまなオブジェクトを区別:非静的内部クラスのオブジェクトはクラスで作成されたとき、新しいキーワード外のオブジェクトによって呼び出されなければならないとき、サブクラスのオブジェクトクラスを作成する場合、オブジェクトはクラスのコンストラクタを呼び出すために外部の発信者として使用する必要があります

外部静的クラスに加えて使用される内部クラス

静的な内部クラスがそのように静的な内部クラスのオブジェクトを作成し、クラスの外のクラスに関連しているため、外部クラスのオブジェクトを作成する必要はありません。

public class CreateStaticInnerInstance {
    public static void main(String[] args) {
        StaticOut.StaticIn in = new StaticOut.StaticIn();
        /* 上面的代码可改为如下两行代码
        使用 OuterClass.InnerClass 的形式定义内部类变量
        StaticOut.StaticIn in;
        通过 new 调用内部类构造器创建静态内部类实例
        in = new StaticOut.StaticIn();
        */
    }
}

静的な内部クラスを呼び出したときに外部のクラスオブジェクトのコンストラクタを使用するので、静的な内部クラスでも比較的単純でサブクラスを作成する必要はありません。次のコードは、空のクラスのサブクラスでは、静的静的インナーStaticInで定義します

public class StaticSubClass extends StaticOut.StaticIn {}

部分的な内部クラス

匿名内部クラス

一度だけ、すぐにクラスの匿名の内部クラスのインスタンスを作成して使用するクラスを作成するための匿名の内部クラスを作成し、クラス定義はすぐに消え、匿名クラスを再利用することはできません。

匿名クラスは、インターフェイスや抽象クラスのインスタンスを作成するために使用されます。

匿名内部クラスはコンストラクタを定義していません。匿名内部クラスは、クラス名ではありませんので、すべてのコンストラクタを定義することはできません。しかし、匿名内部クラスは、初期化ブロックを定義することができ、コンストラクタものは初期化ブロックを完了する必要があり、例として行うことができます。

次の形式で定義された匿名内部クラス:

new 实现接口 | 抽象父类构造器(实参列表)
{
    匿名内部类的类体部分
}

匿名内部クラスを作成し、以下のように最も一般的な方法は、対象のインターフェイスタイプを作成することですされています

public interface ProductA {
    public double getPrice();
    public String getName();
}
public class AnonymousTest {
    public void test(ProductA p) {
        System.out.println("Buy a" + p.getName() + "Cost " + p.getPrice());
    }
    public static void main(String[] args) {
        AnonymousTest ta = new AnonymousTest();
        // 调用 test() 方法时,需要传入一个 Product 参数
        // 此处传入其匿名实现类的实例
        ta.test(new ProductA() {
            @Override
            public double getPrice() {
                return 567.8;
            }

            @Override
            public String getName() {
                return "APG Card";
            }
        });
    }
}

ときに抽象親クラスを継承することにより、匿名内部クラス、匿名内部クラスを作成し、同じ親クラスのコンストラクタのパラメータリストを持つことになります。以下のコードを見てください

public abstract class Device {
    private String name;
    public abstract double getPrice();
    public Device() {};
    public Device(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class AnonymousInner {
    public void test(Device d) {
        System.out.println("Buy a" + d.getName()+ "Cost" + d.getPrice());
    }
    public static void main(String[] args) {
        AnonymousInner ai = new AnonymousInner();
        // 调用有参数的构造器创建 Device 匿名实现类的对象
        ai.test(new Device("电子显示器") {
            @Override
            public double getPrice() {
                return 67.8;
            }
        });

        // 调用无参数的构造器创建 Device 匿名实现类的对象
        Device d = new Device() {
            // 初始化块
            {
                System.out.println("匿名内部类的初始化块");
            }
            // 实现抽象方法
            @Override
            public double getPrice() {
                return 56.2;
            }
            // 重写父类的实例方法
            public String getName() {
                return "keyboard";
            }
        };
        ai.test(d);
    }
}

私は公共の数の関心を歓迎します

おすすめ

転載: www.cnblogs.com/Tianny/p/11609889.html