1. 程式人生 > 實用技巧 >java基礎筆記(十)——java物件

java基礎筆記(十)——java物件

面向過程與面向物件

面向過程 :是一種線性思維, 會按照步驟一步一步的執行,適合處理簡單的問題

面向物件 : 按物件的功能進行呼叫,適合處理複雜的問題

比如: 蓋房子這件事情,

面向過程思想:蓋房子: 備料-打地基-砌牆-封頂-裝修 親力親為的體驗,

面向物件思想:蓋房子: 工程隊 裝修公司 指揮者的體驗

  • 面向過程與面向物件不是對立的,我們處理一件複雜的事情,在巨集觀上採取面向物件的設計思想去分析整個系統,但是具體到微觀上的操作,我們仍然是用面向過程的思路去處理。

什麼是面向物件

  • 面向物件的本質是:以類的方式組織程式碼,以物件的形式封裝資料。

  • 抽象:就是把同一類事物的共性給抽取出來,忽略一些不重要的資訊。比如,我要建立一個員工管理資訊,我只需要得到員工的姓名、性別、出生日期等,對於每一個員工的髮型、衣著,我沒必要去關注。

方法回顧

static方法與非static方法

  • static是隨著類的載入而存在,非static是隨著類的例項而存在,即靜態方法先於非靜態方法存在.因此,在static方法中,呼叫非static方法會報錯。

類和物件

  • 類是對一類事物的抽象,是一個模板。物件是類的一個具體例項。比如,貓是一個抽象的概念,是一個模板,而布偶貓,橘貓是貓的具體例項。

建立物件和初始化

  • 使用new關鍵字建立物件

    • 使用new關鍵字建立的時候,除了分配記憶體空間之外,還會給 建立好的物件 進行預設的初始化 以及對類中構造器的呼叫
  • 類中構造器也稱構造方法,是在進行建立物件的時候必須呼叫的。並且構造器有以下兩個特點:

    • 必須和類的名字相同
    • 必須沒有返回值型別,也不能寫void

如何在ide中檢視.class檔案

  • 點選專案結構-->點選model-->add content root

構造器

  • 特點

    • 必須和類的名字相同‘

    • 必須沒有返回值型別,也不能寫void

      public class Person {
          
          String name;
          int age;
      
          public Person() {
          }
      
          public Person(String name, int age) {
              this.name = name;
              this.age = age;
          }
      }
      
  • 作用

    • 使用new關鍵字,本質是在呼叫構造器
    • 用來初始化物件的值
  • 一旦定義了有參構造器,必須顯示定義無參構造器

java建立物件時的記憶體圖

封裝

  • 作用

    • 提高程式的安全性,保護資料

    • 隱藏程式碼的實現細節

    • 統一介面

    • 增加系統的可維護性

      public class Person {
      
          private String name;
          private int age;
      
          public Person() {
          }
      
          public Person(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              if (age>120 || age<0){
                  this.age = 3;
              }else {
                  this.age = age;
              }
              
          }
      }
      
       public static void main(String[] args) {
      
              Person person = new Person();
      
              person.setName("張三");
              person.setAge(999);
              System.out.println(person.getName() + "的年齡為:" +  person.getAge());
              System.out.println("=================================");
      
              person.setName("李四");
              person.setAge(25);
              System.out.println(person.getName() + "的年齡為:" + person.getAge());
      
          }
      }
      
      

繼承

  • 繼承是對某一批類的抽象,例如,對貓、狗這兩個類進行再次抽象形成動物類

  • 繼承的識別符號是extends,意思是擴充套件。子類是對父類的擴充套件。

  • Java類只有單繼承,沒有多繼承。

  • 所有類都直接或間接繼承object類

  • 子類繼承父類,會繼承父類中的所有非private方法或屬性。

  • ctrl+ h檢視當前類的繼承關係

  • java中的訪問修飾符public、private、protect、default範圍

    • 私有的東西無法被繼承

super關鍵字

  • 通過super關鍵字去呼叫父類中的方法或屬性(非private)

  • new 子類物件時,子類構造器會預設先呼叫父類的構造器,再呼叫自己的構造器。

  • 在子類構造器中,顯示呼叫父類構造器super()時,必須放在子類構造器的第一行。如果先呼叫自己的構造器this()時,也必須放在第一行,也就是說,super()與this()不能同時出現在同一個子類構造器中。

方法重寫

  • 方法重寫的要素

    • 需要有繼承關係,子類繼承父類

    • 方法名相同、引數列表相同、返回值型別相同

    • 修飾符可以擴大但不能縮小:public>protected>default>private

    • 不能重寫父類的私有方法

    • 丟擲的異常可以縮小,但不能擴大。比如父類欠了100萬,子類只能欠的錢小於100萬

  • 為什麼要進行方法重寫

    • 父類的功能子類不一定需要,或者父類的功能不能滿足子類的需要

多型

多型的含義

  • ​ 同一方法可以根據傳送物件的不同而採用不同的行為方式。比如說父類的sleep(){}方法為"躺著睡覺",子類重寫sleep()方法後,其行為變為“站著睡”

  • 一個物件的實際型別是確定的(即再堆空間new的物件是確定的),但指向物件的引用的型別可以有很多(即位於棧中的型別).

  • 多型存在的條件

    • 有繼承關係

    • 子類重寫父類方法

    • 父類引用指向子類物件

  • 注意:多型是方法的多型,屬性沒有多型

  • 向上轉型:父類引用指向子類物件

  • 向下轉型:把父類轉換為子類,需要強制轉換

  • 編譯看左邊,執行看右邊的含義

    instanceOf

  • X instanceof Y:如果X與Y之間存在繼承關係,就返回true

Static關鍵字

  • static只能訪問static修飾的變數或方法,它是隨著類的載入而載入的

  • 非static修飾的可以訪問所有,它是隨著物件的建立而建立的

靜態程式碼塊

public class Person {

    {
        System.out.println("匿名內部類載入...");
    }
    static {
        System.out.println("靜態方法...");
    }

    public Person() {
        System.out.println("構造方法...");
    }
}

public static void main(String[] args) {

      Person person1 = new Person();

        System.out.println("==========");
        Person person2 = new Person();

    }
//執行結果
靜態方法...
匿名內部類載入...
構造方法...
==========
匿名內部類載入...
構造方法...

  • 載入順序:靜態程式碼塊 > 匿名程式碼塊 > 構造方法

  • 靜態程式碼塊會隨著類的載入而載入,並且只加載一次。

  • 匿名程式碼塊優於構造方法載入,可以在匿名程式碼塊中進行一些初始化操作

抽象

//abstract抽象類
public abstract class AbstractDemo {

    //abstract,抽象方法,只有方法名,沒有方法的實現
    public abstract void doSomeThing();
}
  • 抽象類的特點

    • 抽象類的子類必須重寫抽象類的抽象方法,否則這個子類也為抽象類

    • 抽象類不能被例項化,只能通過繼承它的子類例項化物件

    • 抽象類中可以有抽象方法,也可以有普通方法。

    • 抽象類中沒有構造器,不能被例項化。

    • 抽象類是為了提高程式的可擴充套件性。

介面

  • 介面就是定義了一組規範,我們要按照這組規範去實現一些功能。它的本質是契約。就像我們人間的法律一樣,定義好後大家都要去遵守。

  • 介面的格式是public interface

  • 介面可以通過implements實現多個介面

  • 介面中的屬性都是常量,並且被public static final修飾

  • 介面中的方法都是抽象方法,預設被public abstrct修飾

  • 介面中沒有構造器,因此介面不能被例項化

  • 實現介面必須重寫介面中的所有方法

內部類

成員內部類

public class Outer {
    private int age =33;

    public void out(){
        System.out.println("呼叫外部類...");
    }

    public class Inner{

        //呼叫私有方法
        public void getAge(){
            System.out.println("列印外部類中的私有屬性:" + age);
        }

        public void in(){
            System.out.println("呼叫內部類");
        }
    }
}
//main函式
  public static void main(String[] args) {
        //建立外部類物件
        Outer outer = new Outer();
        //建立內部類物件
        Outer.Inner inner = outer.new Inner();
        //呼叫內部類的方法
        inner.in();
        //利用內部類操作外部類的私有屬性
        inner.getAge();
    }
//結果
呼叫內部類
列印外部類中的私有屬性:33
  • 成員內部類可以呼叫外部類中的私有屬性

靜態內部類

  • 靜態內部類不能訪問外部類中的非靜態屬性或方法

匿名內部類

public interface Student {

    void study();
}

public static void main(String[] args) {
        Student student = new Student() {//定義一個匿名內部類並重寫其方法
          @Override
          public void study(){
              System.out.println("學生學習");
          }
        };
        student.study();
    }

異常

異常處理機制的5個關鍵字

  • try:監控可能出現異常的區域

  • catch:捕獲並處理異常資訊

  • finally:無論如何都要執行的程式

  • throw:宣告一個異常物件(預料到了程式將要出現的異常,宣告這個異常物件。程式顯示異常,並停止執行)

  • throws:在方法上宣告一個將要出現的異常(預料到了程式可能出現的異常,並向外丟擲我們處理不了的異常。程式不會停止執行。)

捕獲和處理異常

  • 當捕獲多個異常時,異常需要從小到大捕獲

  • try...catch...finally的快捷鍵:選中程式碼ctrl + alt +t(捕獲並處理異常,不讓程式停下來)

  • throw

    • public class Demo2 {
          public static void main(String[] args) {
              new Demo2().test(1,0);
          }
      
          public static void test(int a,int b){
              if (b==0){
                  //我們知道可能出現一個異常,主動丟擲。通常用在方法中
                  throw new ArithmeticException();
              }
      
          }
      }
      //結果
      Exception in thread "main" java.lang.ArithmeticException
      	at com.oop.demo2.Demo2.test(Demo2.java:11)
      	at com.oop.demo2.Demo2.main(Demo2.java:5)