淺談面向對象思惟

面向對象:

面向對象的三大特性:封裝性、繼承性、多態性java

一:封裝

1.方法就是一種封裝數組

2.關鍵字private也是一種封裝安全

封裝就是將一些細節信息隱藏起來,對於外界不可見ide

package com.dcits.day05.demo03;
​
public class Demo02Method {
    public static void main(String[] args) {
        int[] array = {5,15,25,35,111};
        int max = getMax(array);
        System.out.println(max);
​
    }
    public static int getMax(int[] array) {
        int max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return max;
    }
}
private關鍵字的做用以及使用

一旦使用了private進行修飾,那麼本類中能夠隨意訪問,可是超出了本類的範圍就不能再訪問了this

能夠經過間接訪問的方式,自定義一對兒Getter/Setter方法,必須叫 setXxx 或者是 getXxx3d

對於Getter來講,不能有參數,返回值類型和成員變量對應code

對於Setter來講,不能有返回值,參數類型和成員變量對應對象

// Person類
package com.dcits.day05.demo03;
​
public class Person {
    String name;
    private int age;
    public void show() {
        System.out.println("我叫:" + name  +",今年" + age);
    }
    public void setAge(int num) {
        if (num < 100 && num >=9) {
            age = num;
        } else {
            age = 0;
            System.out.println("數據不合理");
        }
    }
    public int getAge() {
        return age;
    }
}
​
// 調用
package com.dcits.day05.demo03;
​
public class Demo03Person {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "趙麗穎";
//        person.age = 18; 當成員變量被private修飾的時候,外部沒法訪問,只能經過間接的方式Setter,Getter
        person.setAge(-20);
        person.show();
    }
​
}

布爾類型的特殊狀況blog

// 類
package com.dcits.day05.demo03;
​
public class Student {
    private String name;
    private int age;
    private boolean male;
​
    public void setMale(boolean b){
        male = b;
    }
    public boolean isMale() {
        return male;
    }
​
    public void setName(String str){
        name = str;
    }
    public String getName() {
        return name;
    }
    public void setAge(int num) {
        age  = num;
    }
    public int getAge() {
        return age;
    }
}
// 調用
package com.dcits.day05.demo03;
​
public class Demo04Student {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setName("alex");
        stu.setAge(10);
        stu.setMale(true);
​
        System.out.println(stu.getName());
        System.out.println(stu.getAge());
        System.out.println(stu.isMale());
    }
}
​
this關鍵字的使用

當方法的局部變量和類的成員變量重名的時候,根據就近原則,優先使用局部變量,若是須要訪問 本類當中的成員變量,須要使用格式:this.成員變量繼承

經過誰調用的方法,誰就是this

// 類
package com.dcits.day05.demo04;
​
public class Person {
    String name;
    public void sayHi(String name) {
        System.out.println(this.name + "你好,我是" + name);
    }
}
// 調用
package com.dcits.day05.demo04;
​
public class Demo01Person {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "6666";
        person.sayHi("777");
    }
}
構造方法

構造方法是專門用來建立對象的方法,當咱們使用關鍵字new來建立對象的時候,其實就是在調用構造方法

注意事項:

* 構造方法的名稱必須和所在的類名稱徹底同樣,就連大小寫也要徹底同樣
            * 構造方法不要寫返回值類型,連void都不要寫
            * 構造方法不能return一個具體的返回值
            * 若是沒有編寫任何構造方法,那麼編譯器默認會贈送一個構造方法,沒有參數、方法體什麼都不作
            * 一旦編寫了一個構造方法,那麼編譯器就再也不贈送
            * 構造 方法也是能夠重載的
// 類
package com.dcits.day05.demo04;
​
public class Student {
    private String name;
    private int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("有參數的構造方法!!");
    }
    public Student() {
        System.out.println("無參數的構造方法執行啦!!");
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        this.age = age;
​
    }
    public int getAge() {
        return age;
    }
}
// 調用
package com.dcits.day05.demo04;
​
public class Demo02Student {
    public static void main(String[] args) {
        Student stu = new Student();
        Student stu1 = new Student("aaa",20);
        stu1.setAge(23);
        System.out.println(stu1.getAge());
        System.out.println(stu1.getName());
​
    }
​
}
​
局部變量和成員變量
1.定義的位置不同

            * 局部變量:在方法的內部

            * 成員變量:在方法的外部,直接寫在類當中

2.做用範圍不同

            *局部變量:只有方法 纔可使用,出了方法就不能再使用了

            *成員變量:整個類均可以通用

3.默認值不同

            *局部變量:沒有默認值,若是想要用,必須手動賦值

            *成員變量:若是沒有賦值,會有默認值,規則和數組同樣

4.內存的位置不同

            *局部變量:位於棧內存

            *成員變量:位於堆內存

5.生命週期不同

            *局部變量:隨着方法進棧而誕生,隨着方法出棧而消失

            *成員變量:隨着對象建立而誕生,隨着對象被垃圾回收而消失
標準類的組成部分

一個標準的類一般擁有下面的四個部分:

1. 全部的成員變量都要使用private關鍵字來修飾 
        2. 爲每個成員變量編寫一對Getter、Setter方法
        3. 編寫一個無參數的構造方法
        4. 編寫一個全參數的構造方法

二:繼承

繼承是多態的前提,若是沒有繼承,就沒有多態

繼承解決的主要問題就是:共性抽取

定義類時的兩個注意事項:

  • 成員變量時直接定義在類當中的,在方法外面
  • 成員方法不要寫static關鍵字

    繼承的格式:
    // 父類
    package com.dcits.day08.demo01;
    ​
    public class Employee {
    public void method() {
        System.out.println("父類執行!");
    }
    }
    // Teacher子類
    package com.dcits.day08.demo01
    ​
    public class Teacher extends Employee{
    ​
    }
    // Assistant子類
    package com.dcits.day08.demo01;
    ​
    public class Assistant extends Employee {
    }
    // 調用
    package com.dcits.day08.demo01;
    ​
    public class Demo01Extends {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        Assistant assistant = new Assistant();
        teacher.method();
        assistant.method();
    }
    }
    在父子類的繼承關係當中,若是成員變量重名,則建立子類時,訪問有兩種方式:
    • 直接經過子類對象訪問成員變量

      等號左邊是誰,就優先使用誰,沒有則向上找

  • 間接經過成員方法訪問成員變量

    該方法屬於誰,就優先用誰,沒有則向上找
    // 父類
    package com.dcits.day08.demo02;
    ​
    public class Fu {
    int numFu = 10;
    int num = 100;
    public void methodFu() {
        System.out.println(num);
    }
    }
    ​
    // 子類
    package com.dcits.day08.demo02;
    ​
    public class Zi extends Fu {
    int numZi = 20;
    int num = 200;
    public void methodZi() {
        System.out.println(num);
    }
    }
    ​
    // 調用
    package com.dcits.day08.demo02;
    ​
    public class Demo01ExtendsField {
    public static void main(String[] args) {
        Fu fu = new Fu();
        System.out.println(fu.numFu);
    ​
        Zi zi =  new Zi();
        System.out.println(zi.numFu);
        System.out.println(zi.numZi);
    ​
        // 當父類與子類的成員變量重名的時候
        System.out.println(zi.num);
    //        System.out.println(zi.abc);
        //
        zi.methodZi();
        zi.methodFu();
    }
    ​
    ​
    }
    區分子類方法中的三種重名變量
  • 直接使用的方法中的變量
  • this.變量名:調用本類中的成員變量
  • super.變量名:調用父類中的成員變量

    // 父類
    package com.dcits.day08.demo03;
    ​
    public class Fu {
    int num = 10;
    }
    // 子類
    package com.dcits.day08.demo03;
    ​
    public class Zi extends Fu {
    int num = 20;
    public void method() {
        int num = 30;
        System.out.println(num); // 30 局部變量
        System.out.println(this.num); // 20 本類的成員變量
        System.out.println(super.num); // 10 父類的成員變量
    }
    }
    // 調用
    package com.dcits.day08.demo03;
    ​
    public class Demo01ExtendsField {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();
    }
    }
    ​
    繼承中成員方法的訪問特色

    在父子類的繼承關係當中,建立子類對象,訪問成員方法的規則:建立的對象是誰,就優先使用誰,若是沒有則向上找

    注意:不管是成員方法仍是成員變量,若是沒有都是向上找父類u,毫不會向下找子類

    // 父類
    package com.dcits.day08.demo04;
    ​
    public class Fu {
    ​
    public void methodFu() {
        System.out.println("父類中的方法執行啦!");
    }
    ​
    public void method() {
        System.out.println("父類重名執行啦!");
    }
    }
    ​
    // 子類
    package com.dcits.day08.demo04;
    ​
    public class Zi extends Fu {
    public void methodZi() {
        System.out.println("子類中的方法執行啦!");
    }
    public void method() {
        System.out.println("子類重名執行啦!");
    }
    }
    ​
    // 調用
    package com.dcits.day08.demo04;
    ​
    public class Zi extends Fu {
    public void methodZi() {
        System.out.println("子類中的方法執行啦!");
    }
    public void method() {
        System.out.println("子類重名執行啦!");
    }
    }
    繼承方法中的覆蓋重寫

    重寫:方法的名稱同樣,參數列表也同樣,覆蓋、覆寫

重載:方法的名稱同樣,參數列表不同

方法的覆蓋重寫特色:建立的是子類對象,則優先用子類方法

方法覆蓋重寫的注意事項:

  1. 必須保證父子類之間的方法名稱相同、參數列表也相同
  2. @Override:寫在方法前面,用來檢測是否是有效的正確覆蓋重寫,這個註釋就算不寫,只要知足要求,也是正確的覆蓋重寫
  3. 子類方法的返回值必須小於等於父類方法的返回值範圍。Object類是全部類的父類
  4. 子類方法的權限必須大於等於父類方法的權限修飾符。public > protected > (default) > private 注意:(default)不是關鍵字default,而是什麼都不寫,留空
    繼承中方法的覆蓋重寫應用場景
    // 父類
    package com.dcits.day08.demo06;
    // 原本的老款手機
    public class Phone {
    public void   call() {
        System.out.println("打電話");
    }
    ​
    public void send() {
        System.out.println("發短信");
    }
    ​
    public void show() {
        System.out.println("顯示號碼");
    }
    }
    ​
    // 子類
    package com.dcits.day08.demo06;
    // 上市的新款手機
    public class NewPhone extends Phone {
    @Override
    public void show() {
    //        System.out.println("顯示號碼");
        super.show();
        System.out.println("顯示姓名");
        System.out.println("顯示頭像");
    }
    }
    ​
    // 調用
    package com.dcits.day08.demo06;
    ​
    public class Demo01Phone {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.call();
        phone.send();
        phone.show();
        System.out.println("===========");
    ​
        NewPhone newPhone = new NewPhone();
    ​
        newPhone.call();
        newPhone.send();
        newPhone.show();
    }
    }
    繼承中構造方法的訪問特色
    1. 子類構造方法當中有一個默認隱含的 "super()" 調用,因此必定是先調用的父類構造,後執行的子類構造
    2. 子類構造能夠經過super關鍵字來調用父類重載構造
    3. super的父類構造調用,只能是第一個語句 ,不能一個子類構造調用屢次super構造
    4. 子類必須調用父類構造方法,不寫贈送super() 寫了則用寫的指定該的super調用,super只能有一個,還必須是第一個
super關鍵字的用法(訪問父類的內容):
  1. 在子類的成員方法中,訪問父類的成員變量
  2. 在子類的成員方法中,訪問父類的成員方法
  3. 在子類的構造方法中,訪問父類的構造方法
    // 父類
    package com.dcits.day08.demo08;
    ​
    public class Fu {
    int num = 10;
    public void method(){
        System.out.println("父類方法");
    }
    }
    ​
    // 子類
    package com.dcits.day08.demo08;
    ​
    public class Zi extends Fu {
    int num = 20;
    public Zi(){
        super();
    }
    public void methodZi() {
        System.out.println(super.num); // 父類的num
    }
    public void method(){
        super.method();
        System.out.println("子類方法");
    }
    }
    ​
    this關鍵字的三種使用方法(訪問本類的內容)
    1. 在本類的成員方法中,訪問本類的成員變量
    2. 在本類的成員方法中訪問本類的另外一個成員方法
    3. 在本類的構造方法中,訪問本類的另外一個構造方法
      注意:
      • 在第三種用法中要注意:this(..)調用必須是構造方法的一個語句,惟一一個
      • super和this兩種構造調用,不能同時使用
        // 父類
        package com.dcits.day08.demo09;
        ​
        public class Fu {
        int num = 30;
        }
        // 子類
        package com.dcits.day08.demo09;
        ​
        public class Zi extends Fu {
        int num = 20;
        public Zi(){
        this(123); // 本類的無參構造,調用本類的有參構造
        //        this(1,2)
        }
        public Zi(int n){
        ​
        }
        public Zi(int n,int m){
        ​
        }
        public void showNum(){
        int num = 10;
        System.out.println(num);
        System.out.println(this.num); // 本類中的成員變量
        System.out.println(super.num); // 父類中的 成員變量
        }
        public void methodA() {
        System.out.println("AAA");
        }
        public void methodB() {
        methodA();
        this.methodA();
        System.out.println("BBB");
        }
        }
        this、super的關鍵字圖解

        淺談面向對象思惟
        Java語言繼承的三個特色:

      • 一個類的 直接父類只能有惟一一個
      • Java語言能夠多繼承
      • 一個子類的直接父類是惟一的,可是一個父類能夠擁有不少個子類
        淺談面向對象思惟

        三:多態:

        多態的定義以及基本使用

        extends繼承或者implements實現,是多態的前提。
        小明這個對象既有學生形態,也有人類形態。一個對象擁有多種形態,這就是:對象的多態性
        淺談面向對象思惟
        代碼當中體現多態性,其實就是一句話:父類引用指向子類對象

格式:

  • 父類名稱 對象名 = new 子類名稱()
  • 接口名稱 對象名 = new 實現類名稱()

    // 父類
    package com.dcits.day09.demo04;
    ​
    public class Fu {
    public void method(){
        System.out.println("父類方法");
    }
    public void methodFu(){
        System.out.println("父類特有方法");
    }
    }
    // 子類
    package com.dcits.day09.demo04;
    ​
    public class Zi extends Fu {
    @Override
    public void method() {
        System.out.println("子類方法");
    }
    }
    // 調用
    package com.dcits.day09.demo04;
    ​
    ​
    ​
    public class Demo01Multi {
    public static void main(String[] args) {
        // 使用多態的寫法
        // 左側父類的引用指向右側子類的對象
        Fu obj = new Zi();
        // new 的是誰就調用誰 的方法
        obj.method(); // 子類方法
        obj.methodFu(); // 父類特有方法
    }
    }
    ​
    多態中成員變量的使用特色

    訪問成員變量的兩種方式:

    1. 直接經過對象名稱訪問成員變量,看等號左邊是誰,優先用誰,沒有則向上找
    2. 間接經過成員方法訪問成員變量,看該方法屬於誰,優先用誰,沒有則像上找
      // 父類
      package com.dcits.day09.demo05;
      ​
      public class Fu {
      int num = 10;
      ​
      public void showNum(){
      System.out.println(num);
      }
      }
      // 子類
      package com.dcits.day09.demo05;
      ​
      public class Zi extends Fu {
      int num = 20;
      ​
      int age = 16;
      ​
      @Override
      public void showNum() {
      System.out.println(num);
      }
      }
      // 調用
      package com.dcits.day09.demo05;
      ​
      public class Demo01MultiField {
      public static void main(String[] args) {
      Fu obj = new Zi();
      System.out.println(obj.num); // 父類中的10
      System.out.println("=====================");
      obj.showNum(); // 子類沒有覆蓋重寫,就是父類中的num,一旦子類重寫後就是子類中的num
      }
      }
      ​
      多態中成員方法的使用特色

      在多態的代碼當中,成員方法的優先訪問規則是:看new的是誰,就優先用誰,沒有則向上找

注意:編譯看左邊,運行看右邊

對比一下

  • 成員變量:編譯看左邊,運行還看左邊

  • 成員方法:編譯看左邊,運行看右邊
    // 父類
    package com.dcits.day09.demo05;
    ​
    public class Fu {
    int num = 10;
    ​
    public void showNum(){
        System.out.println(num);
    }
    ​
    public void method(){
        System.out.println("父類方法");
    }
    public void methodFu(){
        System.out.println("父類特有方法");
    }
    }
    // 子類
    package com.dcits.day09.demo05;
    ​
    public class Zi extends Fu {
    int num = 20;
    ​
    int age = 16;
    ​
    @Override
    public void showNum() {
        System.out.println(num);
    }
    ​
    @Override
    public void method() {
        System.out.println("子類方法");
    }
    public void methodZi(){
        System.out.println("子類特有方法");
    }
    }
    ​
    // 調用
    package com.dcits.day09.demo05;
    ​
    public class Demo01MultiField {
    public static void main(String[] args) {
       Fu obj = new Zi();
       obj.method(); // 父子都有,優先使用子類
       obj.methodFu(); // 子類沒有,父類有,向上找到父類
        // 編譯看左,左邊是Fu,沒有methodZi方法,因此編譯報錯
    //        obj.methodZi(); // 錯誤寫法
    ​
    //        System.out.println(obj.num); // 父類中的10
    //        System.out.println("=====================");
    //        obj.showNum(); // 子類沒有覆蓋重寫,就是父類中的num,一旦子類重寫後就是子類中的num
    }
    }
    ​
    使用多態的好處

    淺談面向對象思惟

    對象的向上轉型

    對象的向上轉型,其實就是多態寫法

格式: 父類名稱 對象名 = new 子類名稱()

含義:右側建立一個子類對象,把它看成父類來看待使用

注意事項:

  • 向上轉型必定是安全的,從小範圍轉到了大範圍

  • 可是有一個弊端:對象一旦向上轉型爲父類,那麼就沒法調用子類本來的特有內容

相似於:double num = 100 正確 int----double 自動類型轉換
淺談面向對象思惟

// 父類
package com.dcits.day09.demo06;
​
public abstract class Animal {
    public abstract void eat();
}
// 子類
package com.dcits.day09.demo06;
​
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("貓吃魚。。。");
    }
}
​
// 調用
package com.dcits.day09.demo06;
​
public class Demo01Main {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();
    }
​
}
對象的向下轉型

對象的向下轉型,實際上是一個還原動做

格式:子類名稱 對象名 = (子類名稱) 父類對象

含義:將父類對象,還原成爲本來的子類對象

注意事項:

  • 必須保證對象原本建立的時候,就是貓,才能向下轉型成爲貓

  • 若是對象建立的時候原本不是貓,如今非要向下轉型成爲貓,就會報錯

相似於:int num = (int) 10.0 正確 int num = (int) 10.5 錯誤,發生精度損失

// 父類
package com.dcits.day09.demo06;
​
public abstract class Animal {
    public abstract void eat();
}
// 貓子類
package com.dcits.day09.demo06;
​
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("貓吃魚。。。");
    }
​
    public void catchMouse() {
        System.out.println("貓抓老鼠!!");
    }
}
​
// 狗子類
package com.dcits.day09.demo06;
​
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃shit");
    }
​
    public void watchMouse() {
        System.out.println("狗看家!!");
    }
}
​
// 調用
package com.dcits.day09.demo06;
​
public class Demo01Main {
    public static void main(String[] args) {
​
        Animal animal = new Cat(); // 對象的向上轉型
        animal.eat();
​
        // 向下轉型
        Cat cat = (Cat) animal;
        cat.catchMouse(); // 貓抓老鼠!!
​
        // 下面是錯誤的向下轉型
        // 原本new的時候是一隻貓,如今非要轉成狗
        // java.lang.ClassCastException
        Dog dog = (Dog) animal; // 錯誤寫法
​
    }
​
}
​

淺談面向對象思惟

接口多態的綜合案例
// USB接口類:兩個抽象方法:打開USB、關閉USB
package com.dcits.day09.demo07;
​
public interface USB {
​
    public abstract void open();
​
    public abstract void close();
}
​
// 電腦類:開機、關機、鏈接USB接口並對USB設備進行對應操做
package com.dcits.day09.demo07;
​
public class Computer {
    public void powerOn(){
        System.out.println("筆記本電腦開機");
    }
​
    public void powerOff(){
        System.out.println("筆記本電腦關機");
    }
​
    // 使用USB設備的方法,使用接口做爲方法的參數
    public void useDevice(USB usb) {
        usb.open();
        // 判斷當前類是屬於哪一個類以後,在獲取類中的特有方法
        if (usb instanceof Mouse){
            Mouse mouse = (Mouse) usb;
            mouse.click();
        } else if (usb instanceof KeyBoard){
            KeyBoard keyboard = (KeyBoard) usb;
            keyboard.type();
        }
        usb.close();
    }
}
​
// 鼠標類:重寫接口類中的打開、關閉功能,並實現本身的獨有功能
package com.dcits.day09.demo07;
​
public class Mouse implements USB {
    @Override
    public void open() {
        System.out.println("打開鼠標");
    }
​
    @Override
    public void close() {
        System.out.println("關閉鼠標");
    }
​
    public void click(){
        System.out.println("點擊鼠標!");
    }
}
​
// 鍵盤類:重寫接口類中的打開、關閉功能,並實現本身的獨有功能
package com.dcits.day09.demo07;
​
public class KeyBoard implements USB {
    @Override
    public void open() {
        System.out.println("打開鍵盤");
    }
​
    @Override
    public void close() {
        System.out.println("關閉鍵盤");
    }
​
    public void type(){
        System.out.println("敲鍵盤!");
    }
}
相關文章
相關標籤/搜索