Java-物件導向的特徵:封裝、繼承、多型(抽象)

2020-08-10 16:39:11

物件導向特徵:封裝、繼承、多型(抽象)

1.封裝

體現形式—方法、屬性私有化,提供公共存取方式來保證可以進行正常取值和賦值,提高數據安全性

package cn.tedu.fengzhuang;

 

public class FZDemo{

public static void main(String[]args){

//建立物件--具體英雄

Hero h=new Hero();

//給物件屬性進行賦值

/*h.name="亞索";

h.level=1;*/

//呼叫方法來間接給私有化屬性進行賦值

h.setBlood(10);

//展示物件屬性

//呼叫方法來間接給私有化屬性進行取值

//System.out.println(h.name+","+h.getBlood()+","+h.level);

}

}

//代表英雄的類

class Hero{

//屬性

private String name;

private int level;//等級

//private(關鍵字---私有化)

//私有化資訊是不能在外部直接使用的

private int blood;//血量


//快捷鍵---Alt+InsertGenerator---GetterandSetter

public String getName(){

return name;

}

 

public void setName(String name){

this.name=name;

}

 

public int getLevel(){

return level;

}

public void setLevel(int level){

this.level=level;

}

public int getBlood(){

return blood;

}

public void setBlood(int blood){

this.blood=blood;

}



/*//提供間接給私有屬性進行賦值

public void setBlood(int blood){

if(blood<0){

System.out.println("親,您血量給值有問題!!!");

}else{

this.blood=blood;

}

}

//提供間接獲取私有屬性值

public int getBlood(){

return blood;

}*/


/*//有參構造來判斷血量是否小於0

public Hero(int blood){

if(blood<0){

System.out.println("親,您血量給值有問題!!!");

}else{

this.blood=blood;

}

}*/

}

2.繼承

2.1 概念

當多個類中內容出現了重複,把重複內容放到新的類中,通過extends關鍵字讓原來的類和新的類產生關聯關係—繼承。原來的類稱之爲子類/派生類,新的類稱之爲父類別/超類。子類可以獲取父類別部分資訊(子類繼承不了父類別裡私有化資訊,構造方法以及構造程式碼塊)。

package cn.tedu.extends x;

 

public class Extends Demo1{

public static void main(String[]args){

//建立子類物件

Doctor d=new Doctor();

//
d.treat();

}

}


//定義代表醫療人員類

//父類別/超類

class 醫療人員{

//屬性

String name;

int age;

char gender;

//科室

String dept;

 

//方法

public void treat(){

System.out.println(name+"在治病救人...");

}

}



//定義代表醫生的類

//通過extends關鍵字讓醫生類和醫療人員類產生關聯關係---繼承

//子類/派生類

class Doctor extends 醫療人員{

public void treat(){

System.out.println(name+"拿着手術刀在治病救人...");

}

}

 

//定義代表護士的類

class Nurse extends 醫療人員{


}
 
2.2 繼承方式(類與類之間支援單繼承)

子類只能有一個父類別,父類別可以有多個子類
A類繼承B類,B類繼承C類—C類是A類父類別(多級繼承)

2.3 重寫(覆蓋)

當父子類中出現方法簽名一致的方法 遵守重寫原則(兩等兩小一大)
父子類的方法簽名一致
當父類別的方法返回值型別是基本數據型別/void,子類的方法返回值型別就和父類別一致

Class A{

Public void m(){}

}

Class B extends A{

Public void m(){}

}

當父類別方法的返回值型別是參照數據型別,那麼子類的方法返回值型別要麼和父類別方法返回值型別一致要麼是父類別方法返回值型別的子類

Class A{}

Class B extends A{}

Class C{

Public A m(){return null;}

}

Class D extends C{

Public A/B m(){return null;}

}

存取許可權修飾符(根據許可權來限定可以在位置關係下存取資訊)

位置關係(當前存取資訊的地方和資訊定義地方共同作用)—本類、同包類、其他類、子類
在这里插入图片描述

子類方法存取許可權修飾符要麼和父類別存取許可權修飾符一致要麼比父類別存取許可權修飾符範圍要大

Class A{

 void m(){}

}

Class B extends A{

Public void m(){}

}
2.4 super

a.關鍵字,代表父類別物件可以呼叫資訊
b.super語句—在子類構造方法裡呼叫父類別構造,使用時要在首行
c.每個子類構造方法裡預設含有super無參語句來呼叫父類別無參構造,當父類別沒有提供無參構造,子類所有的構造方法需要去手動新增super語句去呼叫父類別對應形式的有參構造
d.保證父類別物件優先於子類物件先存在(父子類執行順序—先執行父類別構造程式碼塊、父類別構造方法、子類構造程式碼塊、子類構造方法)

package cn.tedu.extends x.b;

 

public class Extends Demo3{

public static void main(String[] args){

//建立代表豬的類的物件

Pig p=new Pig(1);

//p.eat();

}

}

//代表動物的類

class Animal{

//無參構造

/*public Animal(){

System.out.println("父類別無參構造");

}*/

//有參構造

public Animal(int j){

System.out.println("父類別有參構造");

}

public void eat(){

System.out.println("在吃東西...");

}

public void sleep(){

System.out.println("在睡覺...");

}

}

//代表豬的類

class Pig extends Animal{

 
//父類別物件優先於子類物件先出現

//無參構造

//子類的所有構造方法裡都預設新增super無參語句來呼叫父類別無參構造

public Pig(){

//super語句---在子類構造方法裡呼叫父類別構造方法,首行使用

super(1);

System.out.println("子類無參構造");

}

//有參構造

//當父類別沒有提供無參構造那麼子類所有的構造方法需要手動新增super語句

//來呼叫父類別對應形式的有參構造

public Pig(int i){

//

super(2);

System.out.println("子類有參構造");

}

//對eat方法進行重寫

public void eat(){

System.out.println("在無憂無慮的吃。。。");

System.out.println("吃飽了。。想睡覺。。。");

//java中所有的非靜態資訊通過物件來呼叫

//this?代表的是當前類的物件

//super代表父類別的物件,可以呼叫父類別資訊

super.sleep();

}

}

3.多型

1.概念

在程式碼操作過程中呈現的多種形式

從java時期角度來進行分析,體現出多型

編譯時多型 在編譯時期系結程式碼(體現形式—過載)

public void m(){}

public void m(int i){}

執行時多型 在執行時期系結程式碼(體現形式–重寫-、向上造型 前提都是繼承)

2.向上造型

向上造型(物件可以呼叫那些方法看父類別,具體方法執行看子類是否有重寫 父類別—目錄 子類—正文)

package cn.tedu.duotai;

public class DTDemo{

public static void main(String[] args){

//養一個寵物
/*Petp;

//養了一隻狗
p=newDog();*/

//當宣告類型別是父類別,實際建立類型別是子類---向上造型
Pet p=new Dog();

//向上造型物件呼叫哪個方法看父類別

//方法的具體執行看子類是否有重寫

p.eat();


//呼叫方法

//匿名物件---當作參數傳遞

m (new Pet());

m (new Dog());

m (new Cat());

}

//參數統一呼叫

public static void m(Petp){//=newPet();=newDog();=newCat();

p.eat();

}

}

//代表寵物的類

class Pet{

public void eat(){

System.out.println("在吃東西....");

}

public void sleep(){

System.out.println("在睡覺...");

}

}

 

//代表狗的類

class Dog extends Pet{

//重寫eat方法

public void eat(){

System.out.println("舔着吃...");

}

public void bark(){

System.out.println("在汪汪汪的叫...");

}

}


//代表貓的類

class Cat extends Pet{

//重寫eat方法

public void eat(){

System.out.println("在呼哧呼哧的吃...");

}

public void 磨爪子(){

System.out.println("在悠閒的磨爪子...");

}

}

3.解釋重寫原則(反證)

1.子類方法存取許可權修飾符要麼和父類別一致要麼比父類別方法存取許可權修飾符範圍要大

Class  A{

       public void m(){}

 }

Class B extends A{

void m(){}

}
A a=new B();//向上造型物件a,宣告類A類,向上造型物件a可以呼叫A類m方法,在任意位置都可以呼叫到m方法。

a.m();//向上造型物件呼叫方法的具體執行看子類是否有重寫,具體呼叫B類裡m方法,在同包範圍內可以被呼叫到。此時前後出現矛盾,證明程式碼是錯的。

2.當父類別方法返回值型別是參照數據型別,那麼子類方法返回值型別要麼和父類別方法返回值型別一致要麼是父類別方法返回值型別的子類

Class A{}

Class B extends A{}

Class C{

Public B m(){return null;}

}

Class D extends C{

Public A m(){return null;}

}

C c=new D();//向上造型的物件c,宣告類是C類,呼叫到C類裡m方法返回B類物件,可以呼叫到B類裡資訊。

A a=c.m();//方法的具體執行看子類是否有重寫,呼叫的是D類裡m方法返回A類的物件,可以呼叫到A類的資訊。此時前後有矛盾,證明程式碼是錯的。
4.優點:

1.統一參數型別
2.解耦(降低耦合度)