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.方便方法的呼叫,減少重複的程式碼!