1. 程式人生 > 其它 >oop三大特性:封裝、繼承、多型

oop三大特性:封裝、繼承、多型

封裝

追求“高內聚,低耦合”
高內聚:就是類的內部資料操作細節自己完成,不允許外部干涉;
低耦合:僅暴露少量的方法給外部使用。


封裝(資料的隱藏)
通常,應禁止直接訪問一個物件中資料的實際表示,而應通過操作介面來訪問,這稱為資訊隱藏。

屬性私有 get/set


private:私有

//屬性私有。  外部無法操作
public class Student{
  private String name;
  private int id;
  private char sex;
  
  //提供一些可以操作這些屬性的方法!
  //提供一些public的get、set方法
  
  //get 獲得這個資料
  public String getName(){
    return this.name;
  }
  
 //set 給這個資料設定值
  public void setName(String name){
    this.name=name;
  }
  
}
public static void main(String[] args){
  Student s1=new Student();
  

  s1.setName("cwj");
    s1.getName();//輸出cwj
  
}

封裝的作用

1.提高程式的安全性,保護資料
2.隱藏程式碼的實現細節
3.統一介面
4.系統可維護增加了


繼承

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

extends的意思是“擴充套件”。子類是父類的擴充套件。

JAVA中類只有單繼承,沒有多繼承!
(一個兒子只能有一個爸爸,但是一個爸爸可以有多個兒子)

繼承是類和類之間的一種關係。除此之外,類和類之間的關係還有依賴、組合、聚合等等。
繼承關係的兩個類,一個為子類(派生類),一個為父類(基類)。
子類繼承父類,使用關鍵字extends

來表示。
子類和父類之間,從意義上講應該具有“is a”的關係。


public是公共的
父類中public類子類可以繼承
private是私有的
父類中private類子類不可以繼承

IDEA中control+h顯示子類父類樹狀圖


super

在子類中重寫父類中的方法。 super.該方法名:直接呼叫父類中的該方法
私有的方法無法呼叫。

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

VS this
代表的物件不同:
this:本身呼叫者這個物件
super:代表父類物件的應用
前提:
this:沒繼承也可以用
super:只能在繼承的條件下才可以使用
構造方法:
this();本類的構造!
super();父類的構造!


方法重寫

重寫:需要有繼承關係,子類重寫父類的方法!
1.方法名必須相同
2.引數列表必須相同
3.修飾符:範圍可以擴大。 public>Protected>Default>private
4.丟擲的異常:範圍可以被縮小,但不能擴大。

重寫:子類的方法和父類要一致,方法體不同!

為什麼要重寫?
1.父類的功能,子類不一定需要,或者不一定滿足!
control+return:override;

public class B{
  public void test(){
    System.out.println("B->test()");
  }
}
public class A extends B{
  //Override 重寫
    public void test(){
    System.out.println("A->test()");
  }
}
public class Demo{
  //靜態方法和非靜態方法區別很大
  		//靜態方法:方法的呼叫只和左邊定義的資料型別有關,和重寫無關
  //非靜態:可重寫
  public static void main(String[] args){
    //方法的呼叫只和左邊,定義的資料型別有關
    A a=new A();
    a.test();//A
    
    //父類的引用指向了子類
    B b=new A();
    b.test();
  }
}
/*最後輸出:
A->test()
A->test()*/

多型

即同一方法可以根據傳送物件的不同而採用多種不同的行為方式
一個物件的實際型別是確定的,但可以指向物件的引用的型別有很多

父類的引用指向子類:

若子類和父類中有相同方法,子類重寫了父類的方法,則執行子類重寫的方法。
但是是父類的引用所以無法執行子類當中獨有的方法

強制轉換後可以使用。

多型注意事項:

1.多型是方法的多型,屬性沒有多型
2.父類和子類,有聯絡。型別轉換異常! ClassCastException
3.存在條件:繼承關係,方法需要重寫,父類引用指向子類物件! Father f1=new Son()

無法重寫的:
1.static 方法 屬於類,它不屬於例項
2.final 常量
3.private 方法

public class Person{
    public void run(){
    
  }
}
public class Student extends Person{
   public void run(){
    System.out.println("son");
  }
  public void eat(){
    System.out.println("eat");
  }
}
public static void main(String[] args){
  //一個物件的實際型別是確定的
  //new Student();
  //new Person();
  
  //可以指向的引用型別就不確定了:父類的引用指向子類
  Student s1=new Student();
  Person s2=new Student();
  //父類的引用指向子類:若子類和父類中有相同方法,子類重寫了父類的方法,則執行子類重寫的方法。
  //但是是父類的引用所以無法執行子類當中獨有的方法
  
  Object s3=new Student();
  
  
  //能執行什麼方法主要看左邊的型別,和右邊的物件關係不大
  s2.run();//子類重寫了父類的方法,執行子類的方法
  
  s1.run();
  
  
}

instanceof操作

滿足(父(子) instanceof 子(父))關係 則為true!反之為false

public static void main(String[] args){
  
  //Object>String 1
  //Object>Person>Teacher 2
  
  //Object>Person>Student  3
  Object object=new Student();
   //滿足(父(子) instanceof 子(父))關係 則為true
     System.out.println(object instanceof Student);//ture
     System.out.println(object instanceof Person);//true
     System.out.println(object instanceof Object);//true
     System.out.println(object instanceof Teacher);//false走的是第2條線
     System.out.println(object instanceof String);//false走的是第1條線
  ---------------------------------------------------
  Person person=new Student();
  System.out.println(person instanceof Student);//true
  System.out.println(person instanceof Person);//true
  System.out.println(person instanceof Object);//true
  System.out.println(person instanceof Teacher);//false 走的是第2條線
 // System.out.println(person instanceof String);編譯報錯
  ----------------------------------------------------
      Student student=new Student();
  System.out.println(student instanceof Student);//true
  System.out.println(student instanceof Person);//true
  System.out.println(student instanceof Object);//true
 // System.out.println(student instanceof Teacher);編譯報錯同等級毫無關係
 // System.out.println(student instanceof String);編譯報錯
  
}

public static void main(String[] args){
  //型別之間的轉化:父        子
  
  //高              低
  Person obj=new Student();
  //將這個物件obj轉換為Student型別,我們就可以使用Student型別的方法了!
  //高轉低。強制轉換
  Student student = (Student)obj;
  ((Student)obj).go();//go為子類獨有的方法 
}

1.父類引用指向子類的物件。
2.把子類轉換為父類,向上轉型:可能會丟失方法
3.把父類轉換為子類,向下轉型:強制轉換
4.方便方法的呼叫,減少重複的程式碼!