Javaのオブジェクト指向の基礎要約記事2

継承、カプセル化、ポリモーフィズム詳細な要約:オブジェクト指向の三つの特徴について主にこの論文。

受け継ぎます

なぜ我々は継承する必要がありますか?

「拡張「」理解の手段を拡張するために英語の文字通りの意味からは、継承は、サブクラスが特徴とコードの再利用を達成するために、親クラスの振る舞いを継承するように、私たちはより簡単に車輪の再発明する必要はありません、拡張クラス、継承を実現することができます。

生命の継承

マッチングのロジックに合わせて継承:「XXはXXである」、限り、この種のものがパスを言うことができるよう、継承の一種です。


図:哺乳動物が来て、それは哺乳動物が動物から継承されることを示す、意味をなすことができる動物である、猫、哺乳動物であり、それは猫が哺乳動物から継承されることを示す、意味をなすことができ。

//示例
public class Test {
  public static void main(String[] args) {
    Student s = new Student(18,"芮耳朵","Java");
    s.study();//继承了父类Person中的方法
    s.play();
  }
}
class Person {
  int age;
  String name;
  public void study() {
    System.out.println("每天进步一点点!");
  }
}
class Student extends Person {
  String major;
  public void play() {
    System.out.println("我喜欢打篮球");
  }
  //构造方法
  public Student(int age, String name, String major) {
    //拥有父类的所有属性
    this.age = age;
    this.name = name;
    this.major = major;
  }
}

/*运行结果是:喜欢Java,每天进步一点点!
             我喜欢打篮球*/

复制代码

演算子instanceofは

instanceofのバイナリ演算子、中国語のように解釈は「...の例は、」オブジェクトの左オペランドは、右のクラスであり、対象が作成されるオブジェクトクラスの右側に残っている場合、falseを返し、そうでない場合はtrue

//示例
public class Test {
  public static void main(String[] args) {
    Student s = new Student(18,"芮耳朵","Java");
    System.out.println(s instanceof Person);
    System.out.println(s instanceof Student); 
  }
}
//运行结果都是true。复制代码

主なポイントの継承をまとめたもの

  • Javaで唯一の単一継承は、C ++多重継承は、その種のようではありません。多重継承は、継承の連鎖は、システムを維持するために、複雑で困難な作り、混乱することができます。
  • Javaクラスは、クラス、インターフェイス、多重継承を継承しません。
  • サブクラスは、すべてのプロパティと親クラス(親クラスのコンストラクタを除く)メソッドを取得するには、親クラスを継承するが、必ずしもそうではないような特性や民間の親クラスのメソッドとして、直接アクセスすることができます。
  • あなたがクラスを定義しない場合、拡張呼び出すことはありません、それは親クラスである:java.lang.Objectの。

オーバーロードされたメソッド(オーバーロード)

同じメソッド名を複数定義することができる過負荷クラスの方法が、方法の異なるパラメータを指します。呼び出されたとき、自動的にマッチング方法は、異なるパラメータに対応します。

オーバーロードメソッドは、それだけで同じ名前で、実際には全く異なるアプローチです!

設定条件:パラメータの種類、新しいパラメータの数、異なる順序で新しいパラメータ

//示例
public static int add(int n1, int n2)public static int add(int n1, int n2, int n3)
//方法名相同,参数个数不同,构成重载。
public static int add(int n1, int n2)public static double add(double n1, int n2)
//方法名相同,参数类型不同,构成重载。
public static int add(int n1, int n2)public static double add(int n1,double n2)
//方法名相同,参数顺序不同,构成重载。复制代码

//示例:只有返回值不同不构成方法的重载
public static int add(int n1, int n2)public static double add(int n1, int n2)
//只有返回值不同,不构成重载。
public static int add(int n1, int n2)public static int add(int num1,int num2)
//只有参数名称不同,不构成重载。复制代码

Objectクラスの基本特性

Objectクラスは、Javaのすべてのクラスの基礎クラスで、すべてのJavaオブジェクトはObjectクラスのプロパティとメソッドを持っています。Javaは、単一継承のみをサポートしているサブクラスは親だけを継承することができ、その後、親クラスは、Javaのクラス編成の便宜のために、また一つだけの親を持ち、クラスで最もラジカルの一つを提供する、すべてのクラスの同等が、このからですクラスが継承され、それはObjectクラスです。いない指定された親クラスは、クラス宣言にキーワードを拡張する場合は、デフォルトではObjectクラスを継承します。

ここで下にあるハッシュコーディング何、背中が関与します。

プログラムが実行されている場合、仮想マシンのメモリ割り当てに多数のオブジェクトがあるかもしれない、それはそれは、これらのオブジェクトのアドレスを見つける必要があるときに実行される、どのような位置にある各オブジェクトのレコードを持つJava仮想マシンテーブル、このテーブルは、一般的にレコードを符号化ハッシュを使用し、各オブジェクトは、独自のハッシュコードを有するデータコンテンツおよびデータ格納アドレス間のマッピング関係を具体化します。しかし、Javaの自身の実現が問題をコーディングハッシュのビットである、それは二つのオブジェクト、異なる内容かもしれませんが、両方のハッシュコード化することも同じで、異なるオブジェクトが時間をコーディングハッシュを計算し、競合を引き起こす可能性があり、いわゆるハッシュ衝突。

Objectクラスのメソッド

文字列との接続の別のタイプの場合は、別のタイプは、自動的に文字列に変換され、文字列は接続されています。参照型がどのようにやっている場合、文字列に二重の基本データ型int、float型は、デジタルへの変換によると、比較的簡単なのですか?学生S1 =新しい学生;文字列s1のプラスこのs1が参照型であるので、あなたは、文字列pにこれを変換する方法がわかりません。この時間toStringメソッドは便利です。

//toString方法:该方法在打印对象时被调用,将对象信息变为字符串返回,默认输出对象地址
//toString方法源码:
public String toString() {
  return getClass().getName() + "@" + Interger.toHexString(hashCode());
  //默认会返回"类名+@+16进制的hashcode"。
  //在打印或者用字符串连接对象时,会自动调用该对象的toString()方法。
}


//示例:toString方法未重载之前
class Person {
    int age;
    String name;
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.age = 18;
        p.name = "芮耳朵";
        //自动调用了toString()方法,简写。
        System.out.println(p);
        //不简写
        System.out.println(p.toString());
      
   }
}
/*运行结果:Person@2a84aee7
           Person@2a84aee7 */
---------------------------------------------------
//示例:toString重载之后
class Person {
    int age;
    String name;
    @Override
    public String toString() {
        return name+",年龄:"+age;
    }
}
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.age = 18;
        p.name = "芮耳朵";
        System.out.println(p);
        System.out.println(p.toString());

    }
}
/*运行结果:芮耳朵,年龄:18
           芮耳朵,年龄:18 */复制代码

superキーワード

Javaクラスでは、新しいオブジェクトが出ているとき、オブジェクトは、オブジェクト自体には、この基準点をこれの参照を持つことになります。新しいオブジェクトがクラスオブジェクトのうちの子供の場合、このサブクラスのこのスーパーの親内の現在のオブジェクトへのスーパーの基準点もあります。このプログラム換算で、我々は、オブジェクト自体を指すようにこれを使用する、親クラス/基本クラス/スーパークラス内の現在のサブクラスのオブジェクトを参照するためにスーパーを使用します。

//示例
class FatherClass {
  public int age;
  public void f() {
      age = 60;
      System.out.println("父类的年龄=" + age);
    }
}
class ChildClass extends FatherClass {
  //子类除了继承父类所具有的age属性外,又声明一个,此时的子类拥有两个age属性。
  public int age;
  //在子类ChildClass里面重写了由父类继承下来的f()方法的方法体。
  public void f() {
    super.f();
    //这里的super作为父类对象的引用对象用来调用父类对象里面的f()方法
    //打印输出语句  
    age = 20;//这个value是子类自己定义的age,不是从父类继承下来的那个age
    System.out.println("子类的年龄=" + age);
    //打印出来的是子类自定义的age值,值为20。
    System.out.println(age);
    System.out.println(super.age);
    }
}
复制代码

//测试类
public class Test {
    public static void main(String[] args) {
        ChildClass cc = new ChildClass();
        cc.f();
    }
}
/* 父类的年龄=60
   子类的年龄=20
   20
   60 */复制代码

パッケージ

パッケージングは​​、内部実装オブジェクトを非表示にすることができ、つまり、オブジェクトのプロパティとメソッドは、単一の全体にパッケージ化、我々は呼び出すために、内部改善が外線通話には影響しません方法を知っている限り呼び出すとき。私たちは、リモートコントロールを使用したのと同様に、あなただけの行を操作する方法を知っておく必要があり、リモートコントロールの内部構造の必要はありません。

なぜパッケージ?

  • コードとデータのこのタイプに対するセキュリティを向上させるためには、ランダムアクセスであり、そのような私たちは、プログラムの中で年齢の私有財産を持っている場合など、外部の問題を修正し、外の世界は、プロパティを設定するには、setメソッドを使用する場合は、外部には、getとsetメソッドを提供しますかどうかを決定する方法で設定することができる時間の値は、通常の年齢制限値に、このように任意に割り当てることができません。
  • コードの再利用を容易にするために、さまざまな方法でパッケージのような、自由に呼び出すことが、必ずしもすべての方法を具体的に繰り返され、良いパッケージを持って、あなただけのコードの量を減らすために呼び出す必要があります、それは簡単なようです。

カプセル化を達成するために

Javaは詳細、公開する必要があるものの詳細をカプセル化する必要があるアクセス指定子を制御するために使用されます。4つのアクセス制御、すなわち、存在するプライベート、デフォルト、保護、公共、私たちは、これにより、安全性の向上、最小限のへのアクセスを行うために、可能な限りそれらを使用する必要がありますが。

プライベート:アクセスの最も厳しいレベルである、あなたがオブジェクトを使用して、唯一の自分のクラスにアクセスすることができ、プライベート表している変数やメソッドプライベートに修正される変数は、外部のパブリッククラスのgetメソッドでアクセスすることができます。

public class Person {
  private int age;
  public int getAge() {  //通过get方法来访问private修饰的变量。
    return this.age;  
 }
  public void setAge(int age) {
    this.age = age;  //通过set方法来修改private修饰的变量。
  }
}复制代码

デフォルトは:それはどの修飾子なしで書くことは何もありません、デフォルト値を示し、同じパッケージにアクセスできる唯一のクラス、使用するオブジェクトがあるクラス、インタフェース、変数やメソッド

//示例
int i = 1;  //没有任何修饰符修饰int。
boolean isTall() {  //没有任何修饰符修饰方法boolean。
  return true;
  }复制代码

保護:クラスが同じパッケージおよびサブクラスへのアクセスおよび他のすべてのパッケージかもしれ表し、それはクラスがこれらの方法および関連する変数を使用していない保護されます。オブジェクトである使用変数やメソッドインターフェイスのインターフェイスとメンバ変数やメソッドは、保護宣言することはできません。

//示例
class Person {
  protected boolean isTall() {
    return true;
  }
}

class Player extends Person {
  protected boolean isTall() {
    //此处省略...重写父类的isTall()方法。
  }
}

//如果把isTall()方法声明为private,那么除了Person之外的类将不能访问。
//如果把isTall()方法声明为public,那么所有的类都可以访问该方法。
//如果只想让isTall()方法对其所在类的子类可见,则将该方法声明为protected。复制代码

公衆:パッケージ内のすべての項目によってアクセス可能なすべてのクラスを示し、オブジェクトが使用するクラス、インタフェース、変数とメソッドを

//示例
//Java程序的main()方法必须设置成public,否则Java解释器将不能运行该类。
public static void main(String[] args) {
  //代码...
  }复制代码

アクセス制御と継承ルール

親クラスのサブクラスで宣言されたパブリックメソッドは、公開でなければなりません。

親クラスで宣言された保護された方法のいずれかであるサブクラスで保護されたとして宣言、またはpublicとして宣言、プライベートにすることはできません。

親クラスで宣言されたプライベートメソッド継承することはできません。

非アクセス修飾子

static修飾子

静的変数:また、クラス変数として知られている静的変数を宣言するために、静的なキーワードを使用してメンバ変数、それは関係なく、静的によるので、それは、静的変数の一つのコピーのみですどのように多くのオブジェクトクラスインスタンスのの、パブリック変数のこの種であります基準値はそのプロパティを変更し、オブジェクトのすべての属性値が変更された結果です。ローカル変数は静的変数として宣言することはできません

静的メソッド:静的メソッドとして宣言された静的メソッドは、あなたが直接アクセスの名前を入力することができ、非静的メソッドは、プロパティやメソッドstatic宣言の呼び出しとすることができ非static宣言のプロパティやメソッドを呼び出すことはできません方法static宣言、非静的変数理由新しいオブジェクトの初期化によって作成され、オブジェクトのクラス名が作成されていないときにメソッドの静的な型を呼び出すことができるので、オブジェクトは静的静的メソッドを使用した場合の特性の非静的メソッドを呼び出して作成されていない場合あるいはにおける方法は、論理的な順序が失敗し、したがって静的メソッド内で非静的メンバにアクセスすることはできないと述べました。

final修飾子

クラスの最終的な宣言を継承することができない使用して、何のクラスは、最終的な任意の特性を継承することができません。コンテンツの方法の最終的な宣言を書き換えることができないとオーバーライド(親クラス及びサブクラスは、同じメソッド名とパラメータを有する)が、過負荷にすることができる過負荷(同じメソッドの名前、異なるパラメータを、すなわち、最も一般的に使用される方法は、コンストラクタのオーバーロードされました) 。変数が一定で、最終的な宣言が変更することはできません変数の最終宣言を使用した場合、すべて大文字にする必要があります。プログラム内の変数がのpublic static final宣言を使用する場合は、変数はグローバル定数となります。

            図:この方法の最終的な変更は上書きすることができません

            図:この方法の最終的な変更は上書きすることができません

abstract修飾子

要約:使用抽象修飾法は、何のメソッド本体、唯一のステートメントはありません定義は、「標準の」実装を提供する抽象メソッドを提供しなければならないサブクラスを伝えることです。

抽象クラス:抽象クラスであるクラスの抽象メソッドが含まれています(サブクラスが抽象クラスでもある場合を除く)仕様で、任意のサブクラスが抽象メソッドのすべてのクラスの抽象親クラスを継承することが定義された抽象メソッドを実装しなければなりません。抽象メソッド宣言では、たとえば、セミコロンで終わる:抽象ボイド研究を();

//示例
abstract class Person {
  abstract public void study();  //抽象方法
}
class Student extends Person {
  //子类必须实现父类的抽象方法,否则编译出错。
  public void study() {
    System.out.println("每天进步一点点!");
  }
}
//测试抽象类
public class Test{
  public static void main(String[] args) {
    Student s1 = new Student();
    s1.study();
  }
}复制代码

抽象クラスは、誘導性要素を使用しています

抽象クラスは継承することができます。

抽象メソッドは実装する必要はありません宣言することです。

この方法は、抽象クラスは抽象クラスとして定義することができる含みます。

抽象メソッド抽象クラスは、プライベートステートメントを使用しないでください。

抽象クラスと抽象メソッドは抽象キーワードを使用して宣言する必要があります。

抽象クラスは、すなわち、新しい抽象クラスをインスタンス化するために使用することはできません、インスタンス化することはできません。

抽象メソッドは、サブクラスだけで抽象クラスではありません、すべての抽象メソッド抽象クラスはオーバーライドする必要があり、キルトクラスを達成しなければなりません。

ポリモーフィズム

多型は、異なる挙動を有していてもよく、異なるオブジェクトに、同じメソッド呼び出しを指します。実生活では、同じ方法で、具体的な実装は完全に異なるものになります。たとえば、次のように同じことが人々の「運動」のアプローチ、日ヤン水泳、バスケットボールはマローンは卓球をプレイしている、ヤオミンで呼び出すことです。運転中に何か違う行動があるかもしれません。

ポリモーフィズム3つの必要な条件が存在します。

1.サブクラスは親クラスを継承しています

2.サブクラスのオーバーライド継承されたメソッド

3.このような親P =新しい子として親クラスのサブクラスオブジェクトへの参照、()。

複数の方法は、状態モードを呼び出すことと、親クラスが、そうでない場合は、記載された方法は、新しいサブクラス定義、コンパイルエラーであるプロセスを最初にチェックがあるかどうか、もしそうであれば、しながら、再びサブクラス同じ名前のメソッドを呼び出します実装は、多型である親、ではありません。

//父类
public class Athlete {
  int age = 10;
  public void exercise() {
    System.out.println("运动员锻炼");
  }
}
//子类
class XunYang extends Athlete {
  int age = 20;
  public void exercise() {
    System.out.println("孙杨游泳锻炼");
  }
  public void run() {
    System.out.println("孙杨正在跑步");
  }
}

//子类觉得父类方法不够好,重写一个!
class YaoMing extends Athlete {
  int age = 30;
  public void excercise() {
    System.out.println("姚明打篮球锻炼");
 }
}

class MaLong extends Athlete {
  int age = 40;
  public void exercise() {
    System.out.println("马龙打乒乓球锻炼");
  }
}复制代码

//测试类1
public class Test {
    public static void main(String[] args) {
        Athlete a = new XunYang();
        a.excercise();
        // a.run(); 编译报错,需要向下强制转型
        System.out.println("年龄是" + a.age);
    }
}
/* 运行结果:孙杨游泳锻炼
            年龄是10 */
复制代码

完全なJava多型の三つの条件を見つけることができる場合にはa.exercise()の呼び出しは、実際に運動のサブクラスですが、a.ageは親クラスや年齢、しかしa.runを(呼び出し)しませんコンパイル。

//测试类2
public class Test {
  public static void main(String[] args) {
    Athlete a1 = new XunYang();  //向上自动转型
    SportsExercise(a1);
    Athlete a2 = new YaoMing();
    SportsExercise(a2);
    Athlete a3 = new MaLong();
    SportsExercise(a3);
      
    //由于这里调用的是自己新的方法,是父类没有的方法。
    //a1.run();编译报错,这里必须要强制向下转型。
    XunYang ath = (XunYang) a1;  
    ath.run();
    System.out.println(("年龄是" + a1.age));  }

  //这里就可以看做是同一个方法“锻炼”,产生多态。
  //如果没有多态,我们这里需要写很多重载的方法
  //每增加一个运动员,就需要重载一个锻炼的方法,非常麻烦
  /* static void Athlete(XunYang x) {
       x.exercise;     
     }
     static void Athlete(YaoMing y) {
       y.exercise;
     }
     ... */
     
    static void SportsExercise(Athlete a) {
    a.exercise();
    }
}
/* 运行结果:孙杨游泳锻炼
            姚明打篮球锻炼
            马龙打乒乓球锻炼  
            孙杨正在跑步
            年龄是10  */复制代码

上記の引数は任意のサブクラスオブジェクトは、オブジェクトの異なるサブクラスの挙動により様々な方法で達成することができるされてもよい、親クラスとのパラメータとしてメソッドの最も一般的な多型の一つを使用することです。


おすすめ

転載: juejin.im/post/5d4bc40651882523942f6b17