02 Java面向對象特點介紹

本質

面向對象編程(Object-Oriented Programming,OOP),本質就是以類的方式組織代碼,以對象的組織(封裝)數據

面向過程是具體的、面向對象是抽象的。

抽象

三大特性: 封裝、繼承、多態

類和對象的關係

是一種抽象的數據類型,它是對某一類事物整體描述/定義,但是並不能代表某一個具體的事物。

例: 動物、植物、手機…

Person類、Pet類、Cat類,這些類都是用來描述/定義某一類具體的事物應該具備的特點和行爲。

對象是抽象概念的具體實例。

例:李四就是人的一個具體實例,李四的狗狗jack就是Cat的一個具體實例

能夠體現出特點,展現出功能的是具體的實例,而不是抽象的概念

創建與初始化對象

使用new關鍵字創建對象

使用new關鍵字創建的時候,除了分配內存空間之外,還會給創建好的對象進行默認的初始化以及對類中構造器的調用。

類中的構造器也稱爲構造方法,是在進行創建對象的時候必須調用的。並且構造器有以下兩個特點:

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

構造器

  • 使用new關鍵字,本質是調用構造器,必須使用構造器
  • 用來初始化值

一旦定義了有參構造,如果想使用無參構造,必須顯示定義無參構造。

封裝

  • 該露的露,該藏的藏

設計程序追求“高內聚、低耦合”。高內聚指的是類的內部數據操作細節自己完成,不允許外部干涉;低耦合指的是盡暴露少量的方法給外部使用。

  • 封裝(數據的隱藏)

    通常,應禁止直接訪問一個對象中數據的實際表示,而應通過操作接口來訪問,這成爲信息隱藏。

屬性私有(private),get/set

繼承

本質是對某一批類的抽象,從而實現對現實世界的更好建模。

extends的意思是“擴展”,子類是父類的擴展。

注意:Java只有單繼承,沒有多繼承。(一個兒子只能有一個爸爸,一個爸爸可以有多個兒子)

  • 繼承是類於類之間的一種關係。除此之外,類與類之間的關係還有依賴、組合和聚合

  • 繼承關係是兩個類。一個父類(基類),一個子類(派生類),子類繼承父類使用extends來表示

  • 子類和父類之間,從意義上講應該是“is a“ 的關係

私有的父類屬性不能繼承。(可以通過get/set來實現繼承)

子類調用父類使用super

public class Stu extends Person{
    private String name = "Halo";
    public void test(String name){
        //這裏的name是調用的test的形參name
        System.out.println(name);
        //這裏的name調用的Stu類中的私有屬性name
        System.out.println(this.name);
        //這裏的name調用的是父類的name屬性
        System.out.println(super.name);
    }
}

執行過程:子類的無參構造中有隱藏的super,所以調用父類的構造器,必須要在子類構造器的第一行。

super注意點

  1. super調用父類的構造方法,必須在構造方法的第一個
  2. super必須只能出現在子類的方法或者構造方法中
  3. super和this不能同時出現在構造方法中

super和this的區別

代表的對象不同:

  • this:本身調用者這個對象
  • super:代表父類對象的應用

前提:

  • this:沒有繼承也可以用
  • super:只能在繼承條件下才可以使用

構造方法:

  • this(); 本類的構造
  • super(); 父類的構造

方法的重寫

重寫都是方法的重寫,和屬性無關!@Override

靜態方法和非靜態方法區別非常大!

靜態方法:方法調用只和左邊定義的數據類型有關。

重寫之和非靜態有關係!

因爲靜態方法

class A extends B{
    public static void test(){
        system.out.println("A->test");
    }
}
class B{
    public static void test(){
        system.out.println("B->test");
    }
}
public static void main(String[] args){
    A a = new A();
    a.test();  //輸出A->test
    B b = new A();
    b.test();   //輸出B->test
}
class A extends B{
    @Override
    public void test(){
        system.out.println("A->test");
    }
}
class B{
    public void test(){
        system.out.println("B->test");
    }
}
public static void main(String[] args){
    A a = new A();
    a.test();  //輸出A->test
    B b = new A();
    b.test();   //輸出A->test
}

重寫:需要有繼承的關係,子類重寫父類的方法!

  1. 方法名必須相同
  2. 參數列表必須相同
  3. 修飾符:範圍可以擴大但不能縮小: public-> protected -> default ->private
  4. 拋出的異常:範圍可以縮小,但不能擴大:ClassNotFoundException -> Exception

重寫:子類的方法和弗雷德必須一致,方法體不同!

Why需要重寫?

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

多態

即同一個方法,可以根據發送對象的不同而採用不同的行爲方式。

一個對象的實際類型是確定的,但是可以指向對象的引用的類型有很多。

  1. 多態是方法的多態,屬性沒有多態!
  2. 父類和子類有聯繫, 沒有關係的會報出類型轉換異常!ClassCastException
  3. 存在的條件:
    • 繼承關係
    • 子類重寫父類的方法,以下方法不會被重寫:
      • static 方法屬於類,不屬於實例
      • final 常量
      • private 方法
    • 父類的引用指向子類 Father F = new Son();

static關鍵字

public class Person{
    {
        System.out.println("匿名代碼塊")}
    static{
        System.out.println("靜態代碼塊")}
    public Person(){
        System.out.println("構造方法")}
    public static void main(String[] args){
        Person person = new Person();
    }
}

執行結果:

​ 靜態代碼塊

​ 匿名代碼快

​ 構造方法

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();
    }
}

執行結果:

​ 靜態代碼塊

​ 匿名代碼快

​ 構造方法

​ ==========

​ 匿名代碼塊

​ 構造方法

靜態導入包

當只導入包中指定的方法,可以使用static關鍵字。例:

import static java.lang.Math.random;
public class Test{
    public static void main(String[] args){
        System.out.println(random());
    }
}

和下面的方式一樣

import static java.lang.Math;
public class Test{
    public static void main(String[] args){
        System.out.println(Math.random());
    }
}

抽象類

是一種約束,有人能幫你實現。abstract,抽象方法,只有方法的名字,沒有方法的實現!

  • 不能new這個抽象類,只能靠子類去實現它;約束!
  • 抽象類中可以寫普通的方法
  • 抽象方法必須在抽象類中

接口

普通類:只能有具體實現

抽象類:具體實現和規範(抽象方法)都有

接口:只是規範,自己無法寫方法~專業的抽象!約束和實現的分離:面向接口的編程(即可以實現多繼承)

聲明類的關鍵字是class,聲明接口的關鍵字是interface

接口就是規範,定義的是一組規則,體現了現實世界中“如果你是…則必須能…”的思想。如果你是貓,就必須會捉老鼠。

接口的本質是契約,就像我們人間的法律一樣。制定好後大家都遵守。

oo的精髓是對對象的抽象,最能體現這一點的就是接口,爲什麼我們討論設計模式都是隻針對具備了抽象能力的語言(比如c++,java,C#等),就是因爲設計模式所研究的,實際上就是如何合理的去抽象。

作用

  • 約束
  • 定義一些方法,讓不同的人實現
  • 方法默認都是public abstract
  • 常量默認都是public static final
  • 接口不能實例化,接口中沒有構造方法
  • implements可以實現多個接口
  • 必須重寫接口中的方法

內部類

內部類就是在一個類的內部定義一個類,比如,A類中定義一個B類,那麼B類相對於A類來說就是稱爲內部類,而A類相對B類磊說就是外部類。

  • 成員內部類
  • 靜態內部類
  • 局部內部類
  • 匿名內部類

成員內部類

通過這個外部類來實例化內部類

public class Outer{
    public class Inner{
        public void in(){
            System.out.println("這是內部類方法")}
    }
}
public class Test{
    public static void mian(String[] args){
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.in();
    }
}   

獲取外部內的私有屬性

public class Outer{
    private int age=10;
    public class Inner{
        public void in(){
            System.out.println("這是內部類方法")}
        public void getAge(){
            System.out.println(age);
        }
    }
}

局部內部類

public class Outer{
    public void method(){
        //在方法中在構建類
        class Inner{
            
        }
    }
}

異常機制

五個關鍵字:
try catch finally throw throws
throw 是語句拋出一個異常;throws 是方法拋出一個異常;

  • throw語法:throw <異常對象>
    在方法聲明中,添加throws子句表示該方法將拋出異常。
  • throws語法:[<修飾符>]<返回值類型><方法名>([<參數列表>])[throws<異常類>]
    【其中:異常類可以聲明多個,用逗號分割。】
  • 處理運行時異常,採用邏輯去合理規避同時輔助try-catch處理
  • 在多重catch塊後面,可以加一個catch(Exception)來處理可能會被遺漏的異常
  • 對於不確定的代碼,也可以加上try-catch,處理潛在的異常
  • 儘量去處理異常,切忌只是簡單的調用printStackTrace()去打印輸出
  • 具體如何處理異常,要根據不同的業務需求和異常類型去決定
  • 儘量添加finally語句去釋放佔用的資源
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章