JavaSE-面向?qū)ο缶幊?/h1>

[TOC]

第一章:面向?qū)ο?概述

1.1-什么是面向?qū)ο螅?/h3>

概述

  • 面向?qū)ο笫且环N程序設計思想号阿。
  • 程序設計的目的是為了用編程解決現(xiàn)實問題习蓬,而面向?qū)ο缶幊痰年P鍵在于強調(diào)對象,用什么對象來完成什么功能
  • 在面向?qū)ο蟪绦蛟O計思想中,任何的事物都可以看作對象昭躺,也就是我們經(jīng)常所說的“萬物皆對象”(一部手機忌锯、一個人、一條狗等等都可以看做是對象)领炫。
  • 對象是由屬性方法組成的偶垮。
    • 屬性:對象的狀態(tài)。
    • 方法:對象的行為或功能帝洪。
    • 圖解對象(比如:一個人)


面向?qū)ο缶幊趟枷?/strong>

? 面向?qū)ο缶幊趟枷刖褪撬贫妫瑢⒄鎸嵤澜绲膹碗s關系,抽象為一個個對象葱峡,然后由對象之間的分工與合作砚哗,完成對真實世界的模擬。(總而言之砰奕,就是找對象做事兒)

  • 真實世界的復雜關系:明確需求
  • 抽象為一個個對象:劃分對象
  • 對象之間的分工與合作:
    • 分工:對象的功能
    • 合作: 對象之間的關系

面向?qū)ο缶幊痰奶攸c

  • 封裝:封裝(encapsulation)就是隱藏對象的屬性和實現(xiàn)細節(jié)蛛芥,僅對外公開接口,控制在程序中屬性的讀取和修改的訪問級別 军援。
  • 繼承: 繼承( inheritance)指的是 子類與父類的關系仅淑,子類可以繼承父類中的屬性和方法
  • 多態(tài): 多態(tài)(Polymorphism)按字面的意思就是“多種狀態(tài)”。在面向?qū)ο笳Z言中胸哥,接口的多種不同的實現(xiàn)方式即為多態(tài)涯竟。

關于對象的三大特征,后續(xù)會逐漸展開講解空厌。

1.2-如何創(chuàng)建和使用對象庐船?

上述講到,要面向?qū)ο缶幊坛案偷谜覍ο笞鍪聝骸?/p>

找對象的前提醉鳖,得先有對象。

現(xiàn)在沒有對象怎么辦哮内?

那就得先創(chuàng)建對象盗棵,創(chuàng)建對象的規(guī)則,需要先知道如何定義

  • 類class北发,是對現(xiàn)實生活中一類具有共同特征的事物的抽象 纹因。

比如,“狗”琳拨,“狗”是類瞭恰,不是一個具體的對象,而是一個抽象的名稱或概念狱庇,泛指世界上“會汪汪叫”惊畏、“對主人忠誠”恶耽、"會看家護院"、“愛啃骨頭”颜启、“有四條腿偷俭、兩只眼睛、一個鼻子缰盏、兩只耳朵等”具有這一系列特征的物種的稱呼涌萤。

所以,類口猜,簡而言之就是一個抽象的概念负溪;

對象

  • 對象,具有屬性方法的一個具體的實例济炎。

類與對象的關系

  • 類是對象的模板川抡,可以用來描述對象的屬性和方法。
  • 對象是類的一個具體實例须尚。對象屬于類猖腕。

定義類

  • 關鍵字:class

  • 定義格式:

    public class 類名 {
        // 成員變量-描述對象的屬性
        // 成員方法-描述對象的方法
    }
    
  • 代碼演示:

    /* 定義類 */
    public class Dog {
      // 成員變量
      String name;
      String type;
      String color;
      // 成員方法
      public void eat(){
        System.out.println("我喜歡啃骨頭");
      }
      public void sound(){
        System.out.println("汪汪~~~");
      }
    }
    

注意:類名單詞的首字母要大寫(比如:Dog

創(chuàng)建和使用對象

  • 關鍵字:new

  • 創(chuàng)建格式:類名 對象名 = new 類名()

  • 使用對象:

    • 操作成員變量:
      • 獲取:對象名.成員變量
      • 設置:對象名.成員變量=值
    • 操作成員方法:
      • 調(diào)用方法:對象名.成員方法()
  • 代碼:

    public class DogTest {
      public static void main(String[] args) {
        // 創(chuàng)建對象
        Dog wangCai = new Dog();
        // 設置對象的屬性-成員變量
        wangCai.name = "旺財";
        wangCai.color = "黃色";
        wangCai.type = "中華田園犬";
        // 讀取對象的屬性
        System.out.println("這一條狗的名字:" + wangCai.name);
        System.out.println("這一條狗狗的毛色:" + wangCai.color);
        System.out.println("這一條狗狗的種族:" + wangCai.type);
        // 調(diào)用對象的方法
        wangCai.eat();
        wangCai.sound();
      }
    }
    
  • 注意:

    • 類是引用數(shù)據(jù)類型恨闪,而對象就是具體的數(shù)據(jù)倘感。
    • 對象的命名和變量命名規(guī)則一樣。

1.3-成員變量的默認值是什么咙咽?

  • 默認值:


  • 代碼:

    public class DogTest02 {
      public static void main(String[] args) {
        Dog wangCai = new Dog();
        // 讀取對象的屬性
        System.out.println("這一條狗的名字:" + wangCai.name);  // null
        System.out.println("這一條狗狗的毛色:" + wangCai.color); // null
        System.out.println("這一條狗狗的種族:" + wangCai.type);  // null
      }
    }
    // 字符串是引用數(shù)據(jù)類型老玛,索引默認值是null
    

1.4-成員變量和局部變量的區(qū)別?

  • 成員變量:定義在類中的方法的變量钧敞。
  • 局部變量:定義在類中的方法內(nèi)的變量蜡豹。
  • 區(qū)別:
    1. 位置不同
      • 成員變量,類中溉苛,方法外镜廉。
      • 局部變量,類中愚战,方法內(nèi)
    2. 作用范圍不同
      • 成員變量娇唯,作用范圍-類中。
      • 局部變量寂玲,作用方法-方法中
    3. 默認值不同
      • 成員變量塔插,有默認值。
      • 局部變量拓哟,沒有默認值想许。并且,使用局部變量時,局部變量必須賦值流纹,否則編譯不通過糜烹。
    4. 內(nèi)存位置不同
      • 成員變量,堆區(qū)
      • 局部變量漱凝,棧區(qū)
    5. 生命周期不同
      • 成員變量疮蹦,隨著對象的創(chuàng)建而創(chuàng)建,隨著對象的銷毀而銷毀碉哑。
      • 局部變量,隨著方法的調(diào)用而創(chuàng)建亮蒋,隨著方法調(diào)用完畢而銷毀扣典。

1.5-圖解內(nèi)存中的對象

一個對象創(chuàng)建并為屬性賦值的內(nèi)存圖

  • Person類代碼

    public class Person {
      // 成員變量
      String name;
      int age;
      // 成員方法
      public void eat(){
        System.out.println("吃飯");
      }
    }
    
  • PersonTest類代碼

    public class PersonTest {
      public static void main(String[] args) {
        Person zs = new Person();
        zs.name = "張三";
        zs.age = 10;
      }
    }
    
  • 內(nèi)存圖解

  • 總結

    1. 對象是引用數(shù)據(jù)類型的數(shù)據(jù)

一個對象調(diào)用方法的內(nèi)存圖

  • Person類代碼-同上

  • PersonTest類代碼

    public class PersonTest {
      public static void main(String[] args) {
        Person zs = new Person();
        zs.name = "張三";
        zs.age = 10;
        // 調(diào)用方法
        zs.eat();
      }
    }
    
  • 內(nèi)存圖解

  • 總結

    1. 調(diào)用方法時,方法會入棧執(zhí)行慎玖,執(zhí)行完畢后會出棧贮尖。

兩個對象調(diào)用方法的內(nèi)存圖

  • Person類代碼-同上

  • PersonTest類代碼

    public class PersonTest {
      public static void main(String[] args) {
        Person zs = new Person();
        zs.name = "張三";
        zs.age = 10;
        zs.eat();
        Person ls = new Person();
        ls.name = "李四";
        ls.age = 11;
        ls.eat();
      }
    }
    
  • 內(nèi)存圖解

  • 總結

    1. new關鍵字創(chuàng)建對象時,都會獨立開辟空間存放對象的信息趁怔。
    2. 所有對象的成員方法都是共享方法區(qū)中的class文件中的方法(節(jié)省內(nèi)存)湿硝。

第二章:面向?qū)ο?封裝

2.1-什么是封裝 ?

? 封裝(encapsulation)就是 隱藏對象的屬性和實現(xiàn)細節(jié)润努,僅對外公開接口关斜,控制在程序中屬性的讀取和修改的訪問級別 。

? 封裝的可以讓代碼更加健壯且易于維護铺浇,提高程序的安全性痢畜。

2.2-如何封裝?

  • private關鍵字修飾成員變量

    • private修飾的成員變量鳍侣,僅能夠在本類中使用丁稀。
    • 格式:private 數(shù)據(jù)類型 成員變量名;
  • 對外提供公開的getXXX/setXXX方法操作對象的屬性。

    • this關鍵字倚聚,在方法中表示調(diào)用方法的對象线衫。
  • 代碼:

    public class Person {
      private String name;
      private int age;
    
      public String getName() {
        return name;
      }
      public void setName(String name) {
        this.name = name;
      }
      public int getAge() {
        return age;
      }
      public void setAge(int age) {
        this.age = age;
      }
    }
    
    

2.3-封裝優(yōu)化-構造方法

什么是構造方法-construction

  • 與類同名的方法

  • 方法修飾沒有返回值類型,沒有void惑折。

    public class Person{
      // 無參構造方法
        public Person(){
            
        }
    }
    

注意:類默認有一個無參的構造方法授账。構造方法可重載

構造方法的作用

  1. 創(chuàng)建對象。
    • 創(chuàng)建對象時惨驶,會默認調(diào)用類的無參構造方法矗积。
  2. 初始化對象的屬性值。
    • 可以定義帶參數(shù)構造方法初始化對象屬性
  • 代碼:

    • Person類

      public class Person {
        private String name;
        private int age;
        // 無參數(shù)構造方法
        public Person() {
        }
        // 有參數(shù)構造方法
        public Person(String name, int age) {
          this.name = name;
          this.age = age;
        }
        public void show(){
          System.out.println("姓名:" + this.name);
          System.out.println("年齡:" + this.age);
        }
      }
      
      
    • 測試類

      public class PersonTest {
        public static void main(String[] args) {
          // 【調(diào)用無參構造方法】
          Person zs = new Person();
          zs.name = "張三";
          zs.age = 10敞咧;
          zs.show(); // 打印結果:姓名:張三  年齡:10
          
          // 【調(diào)用有參構造方法】
          Person ls = new Person("李四",12);
          ls.show(); // 打印結果:姓名:李四 年齡:12
        }
      }
      

2.4-JavaBean

? JavaBean 是 Java語言編寫類的一種標準規(guī)范棘捣。符合 JavaBean 的類,要求類必須是具體的和公共的,并且具有無參數(shù)的構造方法乍恐,提供用來操作成員變量的 set 和 get 方法评疗。

    public class 類名 {
        // 成員變量
        // 無參構造方法【必須】
        // 有參構造方法
        // get/set方法
        // 成員方法
    }

第三章:面向?qū)ο?繼承

3.1-繼承概述?

什么是繼承茵烈?

繼承是子類父類的關系百匆,子類可以使用父類中的成員。

  • 父類:也叫基類或超類呜投。
  • 子類:也叫派生類

例如:現(xiàn)實生活中的繼承


注意:

  • Java的繼承是單繼承加匈,但支持多層繼承。


  • 所有的類都直接或間接的繼承了Object類

    • Object是祖宗類仑荐。
  • 對象 instanceof類 檢測一個對象是否屬于某個類屈嗤。返回布爾值环础,true表示屬于,false表示不屬于。

    • Person類

      public class Person {
      }
      
    • PersonTest類

      public class PersonTest {
        public static void main(String[] args) {
          Person p1 = new Person();
          // p1屬于Person類
          System.out.println(p1 instanceof Person); // 結果:true
          // p1也屬于Object類
          System.out.println(p1 instanceof Object); // 結果:true
        }
      }
      

繼承的作用

  • 實現(xiàn)代碼的復用性涩禀。
  • 提高代碼的可擴展性伙单。

3.2-如何實現(xiàn)繼承瓣履?

關鍵字:extends

  • 格式

    public class 子類 extends 父類 {    
    }
    
  • 代碼:

    • 父類-手機類

      public class Phone {
        private String name;
        private int year;
        public Phone() {
        }
        public Phone(String name, int year) {
          this.name = name;
          this.year = year;
        }
        public String getName() {
          return name;
        }
        public void setName(String name) {
          this.name = name;
        }
        public int getYear() {
          return year;
        }
        public void setYear(int year) {
          this.year = year;
        }
        // 打電話功能
        public void  call(){
          System.out.println("打電話");
        }
        // 發(fā)短信
        public void sendMessage(){
          System.out.println("發(fā)送文字");
        }
        // 手機信息
        public void showInfo(){
          System.out.println("手機名稱:" + this.name);
          System.out.println("生產(chǎn)年份:" + this.year);
        }
      }
      
      
    • 子類-智能手機類

      /*智能手機類*/
      public class IntelligentPhone extends Phone {
        public IntelligentPhone() {
        }
        public IntelligentPhone(String name, int year) {
          super(name, year);
        }
        public void playMusic(){
          System.out.println("播放音樂");
        }
      }
      
    • 測試類

      public class Test {
        public static void main(String[] args) {
          IntelligentPhone iphone = new IntelligentPhone("iphone100",2100);
          iphone.call();  // 打電話
          iphone.sendMessage(); // 發(fā)送文字
          iphone.playMusic(); // 播放音樂
          iphone.showInfo(); // 手機名稱:iphone100 生產(chǎn)年份:2100
        }
      }
      
  • 關鍵字:super,在子類中表示父類的引用檐薯。

    • 在子類中調(diào)用父類構造方法:super(參數(shù)列表)
    • 在子類中調(diào)用父類的非私有的成員變量:super.成員變量名
    • 在子類中調(diào)用父類的非私有的成員方法:super.成員方法()

3.3-方法的重寫-override

  • 子類中的方法和父類中的方法重名時(返回值和參數(shù)列表一致),叫做方法的重載

  • 代碼:

    • 父類-同上手機類

    • 子類

      public class IntelligentPhone extends Phone {
        public IntelligentPhone() {
        }
        public IntelligentPhone(String name, int year) {
          super(name, year);
        }
        public void playMusic(){
          System.out.println("播放音樂");
        }
      
        @Override
        // 重寫父類的方法sendMessage
        public void sendMessage() {
          // 調(diào)用父類的發(fā)送文字的功能
          super.sendMessage();
          // 擴展發(fā)送圖片
          System.out.println("發(fā)送圖片");
        }
      }
      
    • 測試類

      public class Test {
        public static void main(String[] args) {
          IntelligentPhone iphone = new IntelligentPhone("iphone100",2100);
          iphone.sendMessage();
        }
      }
      // 結果:
      // 發(fā)送文字
      // 發(fā)送圖片
      

3.7-抽象類袍冷、抽象方法

抽象類和抽象方法的定義

  • 關鍵字:abstract
  • 抽象方法:只有聲明沒有方法體的方法磷醋。
    • 格式:public abstract 返回值類型 方法名(參數(shù)列表);
    • 一個抽象方法所在的類,該類一定是抽象類胡诗。
    • 抽象方法在子類中必須重寫子檀,除非子類也是抽象類。
  • 抽象類:被abstruct關鍵字修飾的類乃戈。
    • 格式:public abstract class 類名{}
    • 抽象類不能被實例化(不能通過new關鍵字調(diào)用)褂痰。

什么時候適合使用抽象方法

  • 當不同子類有相同的行為,但又有不同的具體實現(xiàn)時症虑,此時父類中定義方法時僅定義聲明即可缩歪。

  • 代碼:需求-創(chuàng)建一條狗對象和一只貓對象,它們有不同的叫聲

    • 父類-Animal

      public abstract class Animal {
        private String name;
        private int age;
        public Animal() {};
        public Animal(String name, int age) {
          this.name = name;
          this.age = age;
        }
        public void sleep(){
          System.out.println("睡覺~~~");
        }
        // 【抽象方法】不同的動物谍憔,叫聲匪蝙,所以讓子類重寫具體的方法體
        public abstract void shout();
        public String getName() {
          return name;
        }
        public void setName(String name) {
          this.name = name;
        }
        public int getAge() {
          return age;
        }
        public void setAge(int age) {
          this.age = age;
        }
      }
      
      
    • 子類-Cat

      public class Cat extends Animal {
        public Cat(){}
        public Cat(String name,int age){
          super(name,age);
        }
        @Override
        public void shout() {
          System.out.println(this.getName() + ":喵喵~~~");
        }
      }
      
    • 子類-Dog

      public class Dog extends Animal {
        public Dog(){};
        public Dog(String name,int age){
         super(name,age);
        }
        @Override
        public void shout() {
          System.out.println(this.getName() + ":汪汪~~~");
        }
      }
      
    • 測試類-Test

      public class Test {
        public static void main(String[] args) {
          Cat cat = new Cat("湯姆",2);
          cat.shout();  //結果: 湯姆:喵喵~~
          Dog dog = new Dog("旺財",3);
          dog.shout(); // 結果: 旺財:汪汪~~
        }
      }
      

3.7-接口

概述

  • 接口,是一系列方法的集合习贫。若類封裝了成員變量逛球、成員方法、構造方法苫昌,而接口主要封裝了方法颤绕。
  • 接口中可以定義抽象方法(jdk7之前)、默認方法和靜態(tài)方法(jdk8)、私有方法(jdk9)以及常量奥务。
  • 接口可以被實現(xiàn)(類似于被繼承)物独,實現(xiàn)接口的類叫做實現(xiàn)類(類似于子類)。
  • 接口中的抽象方法氯葬,實現(xiàn)接口的類必須重寫挡篓。否則,實現(xiàn)類必須是抽象類帚称。
  • 類可以實現(xiàn)多個接口官研。
  • 接口之間可以實現(xiàn)多繼承。

接口的定義和實現(xiàn)

  • 格式

    • 定義接口

      public interface 接口名稱{
          // 【抽象方法】
          public abstract 返回數(shù)據(jù)類型 抽象方法名(參數(shù)列表);
          // 可簡寫為: 返回數(shù)據(jù)類型 抽象方法名(參數(shù)列表);
          // 【默認方法】
          public default 返回數(shù)據(jù)類型 方法名(){
             // 方法體 
          }
          // 【靜態(tài)方法】
          public static 返回數(shù)據(jù)類型 方法名(){
             // 方法體 
          }
          // 【私有方法】
          private 返回數(shù)據(jù)類型 方法名(){
             // 方法體 
          }
      }
      
    • 實現(xiàn)接口:

      public class 實現(xiàn)類名 implements 接口1,接口2...接口n {
          // 重寫接口中的抽象方法【必須】
          // 重寫接口中的默認方法【可選】
      }
      
    • 接口可以繼承其他接口

      public interface 接口1 extends 接口2,接口3...接口n{
          
      }
      
    • 注意:

      1. 抽象方法闯睹,實現(xiàn)類必須重寫
      2. 默認方法戏羽,實現(xiàn)類可以繼承,也可以重寫(可選)
      3. 靜態(tài)方法瞻坝,實現(xiàn)類和實現(xiàn)類的實例無法調(diào)用蛛壳。接口名可以調(diào)用杏瞻。
      4. 常量所刀,實現(xiàn)類可以繼承。
      5. 私有方法捞挥,實現(xiàn)類無法繼承浮创。
  • 代碼:

    • 接口

      public interface CommonInterface {
        // 常量
        public  final double VERSION = 1.0;
        // 抽象方法
        public abstract void fly();
        // 默認方法
        public default void fn(){
          fn1();
          System.out.println("默認方法");
        }
        // 私有方法
        private void fn1(){
          System.out.println("私有方法");
        }
        // 靜態(tài)方法
        public static void show(){
          System.out.println("靜態(tài)方法");
        }
      
      }
      
    • 實現(xiàn)類

      public class Bird implements CommonInterface {
        @Override
        public void fly() {
          System.out.println("展開翅膀飛行");
        }
      }
      
    • 測試類

      public class Test {
        public static void main(String[] args) {
          Bird xn = new Bird();
          xn.fly();
          xn.fn();
        }
      }
      

接口和抽象類的區(qū)別?

  • 相同點
    1. 都可以定義抽象方法砌函。
    2. 都可以實現(xiàn)多態(tài)(第四章)斩披。
    3. 都不可以被實例化。
  • 不同點:
    1. 接口中不可定義成員變量讹俊、構造方法垦沉、成員方法,抽象類可以仍劈。
    2. 接口可以多被多實現(xiàn)(類似多繼承)厕倍。抽象類僅支持單繼承。
    3. 接口可以多繼承其他接口贩疙。抽象類僅支持單繼承讹弯。

什么場景下用繼承類?什么場景下用實現(xiàn)接口这溅?

  • 若強調(diào)多個類是什么時组民,可以使用繼承。

  • 若強調(diào)多個類能做什么時悲靴,可以使用實現(xiàn)接口臭胜。

第四章:面向?qū)ο?多態(tài)

4.1-什么是多態(tài)?

多態(tài)Polymorphism,按字面意思就是“多種狀態(tài)”庇楞。

面向?qū)ο笳Z言中榜配,接口的多種不同的實現(xiàn)方式即為多態(tài) 。

多態(tài)性是允許你將父對象設置成為一個或更多的他的子對象相等的技術吕晌,賦值之后蛋褥,父對象就可以根據(jù)當前賦值給它的子對象的特性以不同的方式運作(摘自“Delphi4 編程技術內(nèi)幕”)。

簡單的說睛驳,就是一句話:允許將子類類型的指針賦值給父類類型的指針烙心。

4.2-多態(tài)的好處?

把不同的子類對象都當作父類來看乏沸,可以屏蔽不同子類對象之間的差異淫茵,寫出通用的代碼,做出通用的編程蹬跃,以適應需求的不斷變化匙瘪。

4.3-如何實現(xiàn)多態(tài)?

實現(xiàn)多態(tài)的前提條件

  1. 繼承或者實現(xiàn)【二選一】
  2. 方法的重寫【意義體現(xiàn):不重寫蝶缀,無意義】
  3. 父類引用指向子類對象【格式體現(xiàn)】

實現(xiàn)方式

  • 格式:父類或被實現(xiàn)的接口 變量名 = new 子類或?qū)崿F(xiàn)類()

  • 代碼:

    • 父類-Animal

      public abstract class Animal {
        private String name;
        private String type;
        public Animal(){}
        public Animal(String name,String type){
          this.name = name;
          this.type = type;
        }
        public abstract void sound();
        public String getName() {
          return name;
        }
        public void setName(String name) {
          this.name = name;
        }
        public String getType() {
          return type;
        }
        public void setType(String type) {
          this.type = type;
        }
      }
      
      
    • 子類-Bird

      public class Bird extends Animal {
        public Bird(){}
        public Bird(String name,String type) {
          super(name,type);
        }
        @Override
        public void sound() {
          System.out.println(this.getName() + ":嘰嘰喳喳~~");
        }
      }
      
    • 子類-Dog

      public class Dog extends Animal {
        public Dog(){}
        public Dog(String name,String type) {
          super(name,type);
        }
        @Override
        public void sound() {
          System.out.println(this.getName() + ":汪汪~~~");
        }
        public void play(){
          System.out.println("狗狗跳起來接飛盤丹喻!");
        }
      }
      
    • 測試類-Test

      public class Test {
        public static void main(String[] args) {
          AnimalSound(new Dog("旺財","中華田園犬"));  // 旺財:汪汪~~~
          AnimalSound(new Bird("小咕","麻雀"));   // 小咕:嘰嘰喳喳~~
        }
        // 動物的叫聲
        public static void AnimalSound(Animal animal){
          animal.sound();
        }
      }
      

4.4-向上向下轉(zhuǎn)型

還是上述代碼,若讓一個Dog對象指向父類的引用翁都,再調(diào)用Dog的play方法時碍论,會編譯出錯!

  • 代碼

    public class Test2 {
      public static void main(String[] args) {
        Animal animal = new Dog("旺財","中華田園犬");
        // animal.play(); // 編譯不通過
      }
    }
    

此時我們可以通過向下轉(zhuǎn)型為Dog對象柄慰,實現(xiàn)對象Dog對象獨有的方法調(diào)用鳍悠。

  • 向上轉(zhuǎn)型:父類/接口 父類引用 = new 子類/實現(xiàn)類()
  • 向下轉(zhuǎn)型:(子類或?qū)崿F(xiàn)類)父類引用

代碼如下:

public class Test2 {
  public static void main(String[] args) {
    Animal animal = new Dog("旺財","中華田園犬");  // 向上轉(zhuǎn)型
    ((Dog) animal).play();  // 狗狗跳起來接飛盤!   // 向下轉(zhuǎn)型
  }
}
  • 注意:

    1. 向下轉(zhuǎn)型時坐搔,若子類不對應藏研,在運行時,會出現(xiàn)ClassCastException異常概行!

    2. 可以通過instanceOf方法檢測蠢挡。

      public class Test2 {
        public static void main(String[] args) {
          Animal animal = new Bird("小咕","麻雀");
          // ((Dog) animal).play();  // ClassCastException 因為向上轉(zhuǎn)型的子類對象不是Dog
          //【正確方式,先驗證類型占锯,再調(diào)用】
          if(animal instanceof Dog){
            ((Dog) animal).play();
          }
        }
      }
      

第五章:面向?qū)ο?其他

5.1-final關鍵字

若定義在父類中的某些成員變量或成員方法袒哥,不希望被子類修改,如何操作呢消略?

可以使用關鍵字final修飾

  • 成員變量
    • 被final修飾的成員變量必須初始化堡称,否則編譯不通過。
    • 被final修飾的成員變量不能重復賦值艺演。
  • 局部變量
    • 被final修飾的局部變量却紧,若不賦值而使用會編譯不通過桐臊。
  • 成員方法
    • 被final修飾的成員方法,不能被重寫晓殊。
  • 成員類
    • 被final修飾的類断凶,不能被繼承。

5.2-權限修飾符

概述

在Java中提供了四種訪問權限巫俺,使用不同的訪問權限修飾符修飾時认烁,被修飾的內(nèi)容會有不同的訪問權限,

  1. public:公共的介汹。
  2. protected:受保護的
  3. default:默認的
  4. private:私有的

不同權限的訪問能力

可見却嗡,public具有最大權限。private則是最小權限嘹承。

編寫代碼時窗价,如果沒有特殊的考慮,建議這樣使用權限:

  • 成員變量使用 private 叹卷,隱藏細節(jié)撼港。
  • 構造方法使用 public ,方便創(chuàng)建對象骤竹。
  • 成員方法使用 public 帝牡,方便調(diào)用方法。

5.3-內(nèi)部類

概述

內(nèi)部類和外部類:將一個類A定義在另一個類B里面瘤载,里面的那個類A就稱為內(nèi)部類否灾,B則稱為外部類卖擅。

內(nèi)部類定義格式

class 外部類 {
    class 內(nèi)部類{ }
}

在描述事物時鸣奔,若一個事物內(nèi)部還包含其他事物,就可以使用內(nèi)部類這種結構惩阶。比如挎狸,汽車類 Car 中包含發(fā)動機

類 Engine ,這時断楷, Engine 就可以使用內(nèi)部類來描述锨匆,定義在成員位置。

class Car { 
    //外部類 
    class Engine {
        //內(nèi)部類 
    } 
}

訪問特點

  • 內(nèi)部類可以直接訪問外部類的成員冬筒,包括私有成員恐锣。
  • 外部類要訪問內(nèi)部類的成員,必須要建立內(nèi)部類的對象舞痰。

創(chuàng)建內(nèi)部類對象

格式:外部類名.內(nèi)部類名 對象名 = new 外部類型().new 內(nèi)部類型()土榴;

  • 人類

    public class Person { 
      private boolean live = true; 
      class Heart { 
          public void jump() { 
              // 直接訪問外部類成員
                if (live) { 
                  System.out.println("心臟在跳動"); 
                } else { 
                  System.out.println("心臟不跳了"); 
                } 
             } 
        }
        public boolean isLive() { 
          return live; 
        }
        public void setLive(boolean live) { 
          this.live = live; 
          }       
    }
    
  • 測試類

    public class Test03   {
      public static void main(String[] args) { 
        // 創(chuàng)建外部類對象 
        Person p = new Person(); 
        // 創(chuàng)建內(nèi)部類對象 
        Heart heart = p.new Heart();
        // 調(diào)用內(nèi)部類方法 
        heart.jump(); 
        // 調(diào)用外部類方法 
        p.setLive(false); 
        // 調(diào)用內(nèi)部類方法 
        heart.jump(); 
      } 
    }
    // 輸出結果: 心臟在跳動 心臟不跳了
    

內(nèi)部類仍然是一個獨立的類,在編譯之后會內(nèi)部類會被編譯成獨立的.class文件响牛,但是前面冠以外部類的類名

$符號 玷禽。 比如赫段,Person$Heart.class

匿名內(nèi)部類介紹

匿名內(nèi)部類 :是內(nèi)部類的簡化寫法。它的本質(zhì)是一個 帶具體實現(xiàn)的 父類或者父接口的 匿名的 子類對象矢赁。

開發(fā)中糯笙,最常用到的內(nèi)部類就是匿名內(nèi)部類了。以接口舉例撩银,當你使用一個接口時给涕,似乎得做如下幾步操作,

  1. 定義子類
  2. 重寫接口中的方法
  3. 創(chuàng)建子類對象
  4. 調(diào)用重寫后的方法

我們的目的额获,最終只是為了調(diào)用方法稠炬,那么能不能簡化一下,把以上四步合成一步呢咪啡?匿名內(nèi)部類就是做這樣的快

捷方式首启。

匿名內(nèi)部類的使用

  • 前提:匿名內(nèi)部類必須繼承一個父類或者實現(xiàn)一個父接口。

  • 格式

    new 父類名或者接口名(){ 
        // 方法重寫 
        @Override 
        public void method() { 
            // 執(zhí)行語句 
        } 
    };
    
  • 代碼

    • Fly接口

      public interface Fly {
        void fly();
      }
      
    • 測試類

      public class Test {
        public static void main(String[] args) {
         /*
           1.等號右邊:是匿名內(nèi)部類撤摸,定義并創(chuàng)建該接口的子類對象 
           2.等號左邊:是多態(tài)賦值,接口類型引用指向子類對象 
         */
          Fly bird = new Fly() {
            @Override
            public void fly() {
              System.out.println("小鳥飛...");
            }
          };
          // 調(diào)用匿名內(nèi)部類重寫后的方法毅桃。
          bird.fly();
      
        }
      }
      

匿名內(nèi)部類的作用

  • 是實現(xiàn)函數(shù)式編程的基礎

5.4-static關鍵字

概述

關于 static 關鍵字的使用,它可以用來修飾的成員變量和成員方法准夷,被修飾的成員是屬于類的钥飞,而不是單單是屬

于某個對象的。也就是說衫嵌,既然屬于類读宙,就可以不靠創(chuàng)建對象來調(diào)用了。

類變量

當 static 修飾成員變量時楔绞,該變量稱為類變量结闸。該類的每個對象都共享同一個類變量的值。任何對象都可以更改

該類變量的值酒朵,但也可以在不創(chuàng)建該類的對象的情況下對類變量進行操作桦锄。

  • 定義格式:修飾符 static 數(shù)據(jù)類型 變量名;
  • 舉例:修飾符 static int age

靜態(tài)方法

當 static 修飾成員方法時蔫耽,該方法稱為類方法 结耀。靜態(tài)方法在聲明中有 static ,建議使用類名來調(diào)用匙铡,而不需要

創(chuàng)建類的對象图甜。調(diào)用方式非常簡單。

  • 定義格式:static 返回值類型 方法名(參數(shù)列表){}

  • 代碼:

    public static void show(){
        System.out.println("hello");
    }
    

注意事項:

  1. 靜態(tài)方法可以直接訪問類變量和靜態(tài)方法鳖眼。
  2. 靜態(tài)方法不能直接訪問普通成員變量或成員方法黑毅。反之,成員方法可以直接訪問類變量或靜態(tài)方法具帮。
  3. 靜態(tài)方法中博肋,不能使用this關鍵字低斋。

靜態(tài)代碼塊

  • 位置:類中方法外
  • 格式:static{}
  • 執(zhí)行:隨著類的加載而執(zhí)行且執(zhí)行一次,優(yōu)先于main方法和構造方法的執(zhí)行匪凡。
  • 作用:給類變量進行初始化賦值
public class ClassName{
    static { 
        // 執(zhí)行語句 
    } 
}

總結

static 關鍵字膊畴,可以修飾變量、方法和代碼塊病游。在使用的過程中唇跨,其主要目的還是想在不創(chuàng)建對象的情況

下,去調(diào)用方法衬衬。下

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末买猖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滋尉,更是在濱河造成了極大的恐慌玉控,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狮惜,死亡現(xiàn)場離奇詭異高诺,居然都是意外死亡,警方通過查閱死者的電腦和手機碾篡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門虱而,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人开泽,你說我怎么就攤上這事牡拇。” “怎么了穆律?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵惠呼,是天一觀的道長。 經(jīng)常有香客問我众旗,道長罢杉,這世上最難降的妖魔是什么趟畏? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任贡歧,我火速辦了婚禮,結果婚禮上赋秀,老公的妹妹穿的比我還像新娘利朵。我一直安慰自己,他們只是感情好猎莲,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布绍弟。 她就那樣靜靜地躺著,像睡著了一般著洼。 火紅的嫁衣襯著肌膚如雪樟遣。 梳的紋絲不亂的頭發(fā)上而叼,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音豹悬,去河邊找鬼葵陵。 笑死,一個胖子當著我的面吹牛瞻佛,可吹牛的內(nèi)容都是我干的脱篙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼伤柄,長吁一口氣:“原來是場噩夢啊……” “哼绊困!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起适刀,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤秤朗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笔喉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體川梅,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年然遏,在試婚紗的時候發(fā)現(xiàn)自己被綠了贫途。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡待侵,死狀恐怖丢早,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秧倾,我是刑警寧澤怨酝,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站那先,受9級特大地震影響农猬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜售淡,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一斤葱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揖闸,春花似錦揍堕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贮泞,卻和暖如春楞慈,著一層夾襖步出監(jiān)牢的瞬間幔烛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工囊蓝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留说贝,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓慎颗,卻偏偏與公主長得像乡恕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子俯萎,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354