Java基礎學習——複習 第四天--面向對象編程

6、面向對象編程

6.1面向對象編程基礎

    (1)面向對象概述

            1.對象:在現實社會中隨處可見的一種食物都是對象,對象是食物存在的實體。通常將對象分爲動態和靜態兩種。靜態即屬性,動態即行爲。

            2.類:類就是同一類事物的統稱。

            3.面向對象程序設計的特點

                3.1封裝--封裝是面向對象編程的核心思想。將對象的屬性和行爲封裝起來,其載體爲類,類通常對對象隱藏其實現細節,這就是封裝思想。採用封裝思想保證了類內部數據結構的完整性,應用該類的用戶不能輕易地直接操作此數據結構,之恩能夠執行類允許公開的數據,這樣避免了外部操作對內部數據的影響,提高了程序的可維護性。

                3.2繼承--類與類之間的關係,繼承是其一種,繼承主要是利用特定對象之間的共有屬性

                3.3多態--將父類對象應用於子類的特徵就是多態。

        (2)類與對象

                1.成員變量--在java中對象的屬性也稱爲成員變量,成員變量的定義與普通變量的定義一樣。語法 數據類型 變量名[= 值]   其中[= 值]是可選內容,定義變量時可以爲其賦值也可以不賦值。

                2.成員方法--在java中,成員方法對應於類對象的行爲,它主要用來定義類可執行的操作,他是包含一系列語句的代碼塊。

                    2.1成員方法的定義--語法:[權限修飾符][返回值類型]方法名([參數類型 參數名])[throws 異常類型]{

                                                                 …//方法體

                                                                 return 返回值;

                                                                 }

                    2.2成員方法的參數--調用方法時可以給該方法傳遞一個或多個值,傳給內部方法叫實參,在方法內部接受實參的變量叫形參,形參的聲明語法與變量的聲明語法一樣,形參只在方法內部有效

                        2.2.1值參數--表明實參和形參之間按值傳遞,當值參數被調用時編譯器爲形參分配存儲單元,然後將對應的實參的值複製到形參中,由於是值類型的傳遞方式,所以在方法中對值類型的形參的修改不會影響到實參。

                        2.2.2引用參數--如果在給方法傳遞參數時,參數的類型是數組或其他的引用類型,那麼在方法中對參數的修改會反映到原有的數組或其他引用類型上,這種類型的參數稱之爲引用參數。

                        2.2.3不定長參數--聲明方法時,如果有若干個相同類型的參數,可以定義爲不定長參數,

方法:權限修飾符 返回值類型 方法名(參數類型 …參數名)

                   2.3成員方法的使用

代碼實現:

 public class Leopard {

       public voidgaze(String target) {// 凝視。目標是參數target

              System.out.println("獵豹凝視:"+ target);

       }

 

       public voidrun() {// 奔跑

              System.out.println("獵豹開始奔跑");

       }

 

       public booleancatchPrey(String prey) {// 捕捉獵物,返回捕捉是否成功

              System.out.println("獵豹開始捕捉"+ prey);

              returntrue;// 返回成功

       }

 

       public voideat(String meat) {// 吃肉,參數是肉

              System.out.println("獵豹吃"+ meat);

       }

 

       public voidsleep() {// 睡覺

              System.out.println("獵豹睡覺");

       }

 

       public staticvoid main(String[] args) {

              Leopard liebao= new Leopard();

              liebao.gaze("羚羊");

              liebao.run();

              liebao.catchPrey("羚羊");

              liebao.eat("羚羊肉");

              liebao.sleep();

       }

}

結果:

獵豹凝視:羚羊
獵豹開始奔跑
獵豹開始捕捉羚羊
獵豹吃羚羊肉

獵豹睡覺

                3.構造方法--構造方法是一個與類同名的方法,對象的創建就是通過構造方法完成的。

構造方法的特點:(1)構造方法沒有返回類型,也不能定義爲void(2)構造方法的名稱要與本類的名稱相同(3)構造方法的主要作用就是完成對象的初始化工作,他能把定義對象的參數傳遞給對象成員。

                4.局部變量--在成員方法中定義一個變量,那麼這個變量就稱爲局部變量,局部變量在方法中被執行時創建,方法結束時銷燬。

                5.局部變量的有效範圍--局部變量的有效範圍從該變量的聲明開始到該變量的結束爲止。

                6.對象的創建--在java語言中使用new創建對象。語法 Test test =new Test();

                7.訪問對象的屬性和行爲--用戶使用new操作符創建一個對象後,可以使用“對象.類成員”來獲取對象的屬性和行爲。當對象獲取類成員時,也相應的獲取了對象的屬性和行爲

                8.對象的銷燬--java會對一下兩種情況的對象進行銷燬(1)對象引用超過其作用範圍,(2)講對象賦值爲null。

                9.this關鍵字--明確引用的是類成員還是局部變量或者方法參數等。

        (3)static 關鍵字--由static 修飾的變量、常量和方法被稱作靜態變量、靜態方法、靜態常量。

                1.靜態變量--java程序中把共享的變量用static修飾,該變量就是靜態變量。

                2.靜態常量--在java中用 final static 修飾一個成員變量,這個成員變量就是一個靜態常量。

                3.靜態方法--java中用static修飾的方法就是靜態方法。

                4.靜態代碼塊--用static修飾的代碼區域爲靜態代碼塊。

         (4)類的主方法--主方法是類的入口點,他定義了程序從何處開始;主方法提供對程序控制流向的控制;

主方法的語法:public static void main(String [] args){

//方法體

}

6.2面向對象核心技術

        (1)類的封裝

代碼實現:

public classRestaurant4 {

        privateCook2 cook = new Cook2();// 餐廳封裝的廚師類

 

        publicvoid takeOrder(String dish) {// 下單

                 cook.cooking(dish);//通知廚師做菜

                 System.out.println("您的菜好了,請慢用。");

        }

 

        publicString saySorry() {// 拒絕顧客請求

                 return"抱歉,餐廳不提供此項服務。";

        }

 

        publicstatic void main(String[] args) {

                 Restaurant4water = new Restaurant4();// 創建餐廳對象,爲顧客提供服務

                 System.out.println("**請讓廚師爲我做一份香辣肉絲。***");

                 water.takeOrder("香辣肉絲");//服務員給顧客下單

                 System.out.println("**你們的廚師叫什麼名字?***");

                 System.out.println(water.saySorry());//服務員給顧客善意的答覆

                 System.out.println("**請讓廚師給我切一點蔥花。***");

                 System.out.println(water.saySorry());///服務員給善意的答覆顧客

        }

}

結果

**請讓廚師爲我做一份香辣肉絲。***
Tom Cruise洗蔬菜
Tom Cruise切蔥花
Tom Cruise開始烹飪香辣肉絲
您的菜好了,請慢用。
**你們的廚師叫什麼名字?***
抱歉,餐廳不提供此項服務。
**請讓廚師給我切一點蔥花。***

抱歉,餐廳不提供此項服務。

封裝的思想就是對客戶隱藏其細節,

        (2)類的繼承--及城市程序開發中重要的概念,使整個程序架構具備一定的彈性,減少開發週期,提高軟件的可維護型和可擴展性。

                1.extends關鍵字--java中讓一個類繼承另一個類,用extends關鍵字,語法:子類 extends 父類

                2.方法的重寫

                    2.1重寫的實現--重寫就是在子類中將父類的成員方法的名稱保留,重新編寫成員方法的實現內容,更改成員方法的存儲權限,或是修改成員方法的返回值類型。在繼承中還有一種特殊的重寫方式,子類與父類的成員方法返回值,方法名稱、參數類型及個數完全相同,唯一不同的世方法實現內容,這種特殊的重寫方法叫重構。

                    2.2super關鍵字--用來在方法重寫後調用父類的屬性和方法。

                3.所有類的父類——Object類--所有類都直接或間接的繼承了java.lang.Object類,下面介紹幾個重要方法

                    3.1getClass()方法--他會返回對象執行時的class實例,然後使用此實例調用getName方法獲取類的名稱

                    3.2toString()方法--將一個對象返回爲字符串形式,會返回一個String實例

                    3.3equals()方法--比較的是兩個對象的實際內容

        (3)類的多態

                1.方法的重載--在同一個類中允許同時存在一個以上的同名方法,只要這些方法的參數個數或類型不同即可。

代碼實現:

public classOverLoadTest {

        //定義一個方法

        publicstatic int add(int a) {

                 returna;

        }

        //定義與第一個方法參數個數不同的方法

        publicstatic int add(int a, int b) {

                 returna + b;

        }

        //定義與第一個方法相同名稱、參數類型不同的方法

        publicstatic double add(double a, double b) {

                 returna + b;

        }

        //定義一個成員方法

        publicstatic int add(int a, double b) {

                 return(int) (a + b);

        }

        //這個方法與前一個方法參數次序不同

        publicstatic int add(double a, int b) {

                 return(int) (a + b);

        }

        //定義不定長參數

        publicstatic int add(int... a) {

                 ints = 0;

                 //根據參數個數循環操作

                 for(int i = 0; i < a.length; i++) {

                         s+= a[i];// 將每個參數的值相加

                 }

                 returns;// 將計算結果返回

        }

        publicstatic void main(String args[]) {

                 System.out.println("調用add(int)方法:" + add(1));

                 System.out.println("調用add(int,int)方法:" + add(1,2));

                 System.out.println("調用add(double,double)方法:" + add(2.1,3.3));

                 System.out.println("調用add(int a,double b)方法:" + add(1, 3.3));

                 System.out.println("調用add(doublea, int b) 方法:" + add(2.1, 3));

                 System.out.println("調用add(int...a)不定長參數方法:"+ add(1, 2, 3, 4, 5, 6, 7, 8, 9));

                 System.out.println("調用add(int...a)不定長參數方法:" + add(2, 3, 4));

        }

}

結果:

調用add(int)方法:1
調用add(int,int)方法:3
調用add(double,double)方法:5.4
調用add(int a, double b)方法:4
調用add(double a, int b) 方法:5
調用add(int... a)不定長參數方法:45
調用add(int... a)不定長參數方法:9

                2.向上轉型--將具體類轉換爲抽象類

代碼實現

classQuadrangle {                                            //四邊形類

        publicstatic void draw(Quadrangle q) {//四邊形類中方法

                 //SomeSentence

        }

}

 

public classParallelogram extends Quadrangle {

        publicstatic void main(String args[]) {

                 Parallelogramp=new Parallelogram();

                 draw(p);

        }

}


                3.向下轉型--將抽象類轉化爲具體類

代碼

classQuadrangle {

        publicstatic void draw(Quadrangle q) {

                 //SomeSentence

        }

}

 

public classParallelogram extends Quadrangle {

        publicstatic void main(String args[]) {

                 draw(newParallelogram());

                 //將平行四邊形類對象看作是四邊形對象,稱爲向上轉型操作

                 Quadrangleq = new Parallelogram();

                 Parallelogramp = (Parallelogram) q; // 將父類對象賦予子類對象

                

                 ////將父類對象賦予子類對象,並強制轉換爲子類型

                 //Parallelogramp = (Parallelogram) q;

        }

}

                4.instanceof關鍵字--判斷是否一個類實現了某個接口,也可以用它來判斷一個實例對象是否屬於一個類

代碼實現

class Quadrangle {

        publicstatic void draw(Quadrangle q) {

                 //SomeSentence

        }

}

 

class Square extends Quadrangle {

        //SomeSentence

}

 

class Anything {

        //SomeSentence

}

 

public class Parallelogram extendsQuadrangle {

        publicstatic void main(String args[]) {

                 Quadrangleq = new Quadrangle(); // 實例化父類對象

                 //判斷父類對象是否爲Parallelogram子類的一個實例

                 if(q instanceof Parallelogram) {

                         Parallelogramp = (Parallelogram) q; // 進行向下轉型操作

                 }

                 //判斷父類對象是否爲Parallelogram子類的一個實例

                 if(q instanceof Square) {

                         Squares = (Square) q; // 進行向下轉型操作

                 }

                 //由於q對象不爲Anything類的對象,所以這條語句是錯誤的

                 //System.out.println(q instanceof Anything);

        }

}


        (4)抽象類與接口

                1.抽象類與抽象方法--定義抽象類時,需要使用abstract關鍵字

代碼實現:

public abstract class Market {

        publicString name;//商場名稱

   public String goods;//商品名稱

   public abstract void shop();//抽象方法,用來輸出信息

}

public classTaobaoMarket extends Market {

    @Override

        publicvoid shop() {

                 //TODO Auto-generated method stub

                 System.out.println(name+"網購"+goods);

        }

}

public classWallMarket extends Market {

        @Override

        publicvoid shop() {

                 //TODO Auto-generated method stub

                 System.out.println(name+"實體店購買"+goods);

        }

 

}

/**

 * 使用抽象類模擬“去商場買衣服”的案例,然後通過派生類確定到底去哪個商場買衣服,買什麼樣的衣服。

 */

public classGoShopping {

        publicstatic void main(String[] args) {

                 Marketmarket = new WallMarket();// 使用派生類對象創建抽象類對象

                 market.name= "沃爾瑪";

                 market.goods= "七匹狼西服";

                 market.shop();

                 market= new TaobaoMarket();// 使用派生類對象創建抽象類對象

                 market.name= "淘寶";

                 market.goods= "韓都衣舍花裙";

                 market.shop();

        }

}

結果:

沃爾瑪實體店購買七匹狼西服

淘寶網購韓都衣舍花裙

使用抽象類和抽象方法時,需要遵循以下原則

1)在抽象類中,可以包含抽象方法,也可以不包含抽象方法,但是包含了抽象方法的類必須被定義爲抽象類

2)抽象類不能直接實例化,即使抽象類中沒有聲明抽象方法,也不能實例化

3)抽象類被繼承後,子類需要實現其中所有的抽象方法

4)如果繼承抽象類的子類也被聲明爲抽象類,則可以不用實現父類中所有的抽象方法

                2.接口的聲明及實現--接口是抽象類的延伸,接口中所有方法都沒有方法體

代碼實現:

interfacedrawTest { // 定義接口

        publicvoid draw(); // 定義方法

}

 

// 定義平行四邊形類,該類實現了drawTest接口

classParallelogramgleUseInterface implements drawTest {

        publicvoid draw() { // 由於該類實現了接口,所以需要覆蓋draw()方法

                 System.out.println("平行四邊形.draw()");

        }

}

 

// 定義正方形類,該類實現了drawTest接口

classSquareUseInterface implements drawTest {

        publicvoid draw() {

                 System.out.println("正方形.draw()");

        }

}

 

public classQuadrangleUseInterface { // 定義四邊形類

        publicstatic void main(String[] args) {

                 drawTest[]d = { // 接口也可以進行向上轉型操作

                                  newSquareUseInterface(), new ParallelogramgleUseInterface() };

                 for(int i = 0; i < d.length; i++) {

                         d[i].draw();// 調用draw()方法

                 }

        }

}

結果

正方形.draw()
平行四邊形.draw()

                3.多重繼承--java中實現多重繼承,須使用接口

代碼實現:

public interfaceIFather {// 定義一個接口

        voidsmoking();// 抽菸的方法

 

        voidgoFishing();// 釣魚的方法

}

public interfaceIMather {// 定義一個接口

        voidwatchTV();// 看電視的方法

 

        voidcooking();// 做飯的方法

}

public classMe implements IFather, IMather {// 繼承IFather接口和IMather接口

 

        @Override

        publicvoid watchTV() {// 重寫watchTV()方法

                 System.out.println("我喜歡看電視");

        }

 

        @Override

        publicvoid cooking() {// 重寫cook()方法

                 System.out.println("我喜歡做飯");

        }

 

        @Override

        publicvoid smoking() {// 重寫smoke()方法

                 System.out.println("我喜歡抽菸");

        }

 

        @Override

        publicvoid goFishing() {// 重寫goFishing()方法

                 System.out.println("我喜歡釣魚");

        }

 

        publicstatic void main(String[] args) {

                 IFatherfather = new Me();// 通過子類創建IFather接口對象

                 System.out.println("爸爸的愛好:");

                 //使用接口對象調用子類中實現的方法

                 father.smoking();

                 father.goFishing();

                 IMathermather = new Me();// 通過子類創建IMather接口對象

                 System.out.println("\n媽媽的愛好:");

                 //使用接口對象調用子類中實現的方法

                 mather.cooking();

                 mather.watchTV();

        }

}

結果:

爸爸的愛好:
我喜歡抽菸
我喜歡釣魚


媽媽的愛好:
我喜歡做飯
我喜歡看電視

                4.區分抽象類與接口--抽象類是對根源的抽象,接口是對動作的抽象

抽象類與接口的不同

比較項

抽象類

接口

方法

可以有非抽象類

所有方法都是抽象方法

屬性

屬性中可以有非靜態常量

所有的屬性都是靜態常量

構造方法

有構造方法

沒有構造方法

繼承

一個類只能繼承一個父類

一個類可以同時實現多個接口

被繼承

一個類只能繼承一個父類

一個接口可以同時繼承多個接口

 


        (5)訪問控制

                1.訪問控制符

Java語言中的訪問控制符權限

 

Public

Protected

Default(缺省)

Private

本類

可見

可見

可見

可見

本類所在包

可見

可見

可見

不可見

其他包中的子類

可見

可見

不可見

不可見

其他包中的非子類

可見

不可見

不可見

不可見

 使用訪問控制符時,需要遵循以下原則:

1)大部分頂級類都是用public修飾;

2)如果某個類主要用作其他類的父類,該類中包含的大部分方法只是希望被其子類重寫,要不想被外界直接調用,則應該使用protected修飾;

3)類中的絕大部分屬性都應該使用private修飾,除非一些static或者類似全局變量的屬性,才考慮使用public修飾;

4)當定義的方法只是用於輔助實現該類的其他方法(即工具方法),應該使用private修飾;

5)希望允許其他類自由調用的方法應該使用public修飾。

                2.java類包--類包不僅可以解決類名衝突問題,還可以在開發龐大的應用程序是,幫助開發者管理龐大的應用程序組件,方便軟件複用

                3.final關鍵字

                    3.1final類--定義爲final不能被繼承。

                    3.2final方法--final方法不能被重寫,可以防止子類修改該類的定義與實現方式,同時定義final的方法執行效率遠高於非final方法。

                    3.3final變量--用於變量聲明,一旦該變量被設定,就不可以在改變該變量的值。

        (6)內部類

                1.成員內部類

                    1.1成員內部類的簡介--在一個類中使用內部類,可以直接存取其所在類的私有成員變量。

語法:public class OuterClass{//外部類

        private class InnerClass{//內部類

            //……

}

}

                    1.2內部類向上轉型爲接口

代碼實現:

interfaceOutInterface { // 定義一個接口

        publicvoid f();

}

 

public classInterfaceInner {

        publicstatic void main(String args[]) {

                 OuterClass2  out = new OuterClass2 (); // 實例化一個OuterClass2對象

                 //調用doit()方法,返回一個OutInterface接口

                 OutInterfaceoutinter = out.doit();

                 outinter.f();// 調用f()方法

        }

}

 

classOuterClass2  {

        //定義一個內部類實現OutInterface接口

        privateclass InnerClass implements OutInterface {

                 InnerClass(Strings) { // 內部類構造方法

                         System.out.println(s);

                 }

 

                 publicvoid f() { // 實現接口中的f()方法

                         System.out.println("訪問內部類中的f()方法");

                 }

        }

 

        publicOutInterface doit() { // 定義一個方法,返回值類型爲OutInterface接口

                 returnnew InnerClass("訪問內部類構造方法");

        }

}

                    1.3使用this關鍵字獲取內部類與外部類的引用--在外部類與內部類的成員變量名稱相同時可以使用this關鍵字

                2.局部內部類--可以在類的局部位置進行定義。

代碼實現:

interface OutInterface2 { // 定義一個接口

}

class OuterClass3 {

        publicOutInterface2 doit(final String x) { // doit()方法參數爲final類型

                 //在doit()方法中定義一個內部類

                 classInnerClass2 implements OutInterface2 {

                         InnerClass2(Strings) {

                                  s= x;

                                  System.out.println(s);

                         }

                 }

                 returnnew InnerClass2("doit");

        }

}

內部類被定義在了doit()方法內部。在doit()方法外部無法訪問該內部類,但該內部類可以訪問當前代碼塊的常量以及此外部類的所有成員

                3.匿名內部類

代碼實現

interfaceOutInterface2 { // 定義一個接口

}

 

classOuterClass4 {

        publicOutInterface2 doit() { // 定義doit()方法

                 returnnew OutInterface2() { // 聲明匿名內部類

                         privateint i = 0;

 

                         publicint getValue() {

                                  returni;

                         }

                 };

        }

}

使用匿名內部類應該遵循以下原則:

1)匿名類沒有構造方法

2)匿名類不能定義靜態的成員

3)匿名類不能用private、public、protected、static、final、abstract等修飾符

4)只可以創建一個匿名類實例。

                4.靜態內部類--在內部類前加static修飾,該內部類就是靜態內部類(在程序開發中比較少見)

                5.內部類的繼承--需要設置專門的語法來完成

代碼實現

public classOutputInnerClass extends ClassA.ClassB { // 繼承內部類ClassB

        publicOutputInnerClass(ClassA a) {

                 a.super();

        }

}

 

class ClassA{

        classClassB {

        }

}

在某個類繼承內部類時,必須硬性的給予這個類一個帶參數的構造方法,並且該構造方法的參數必須是該內部類的外部類引用,就像例子中的ClassA  a,同時在構造方法體重使用a.super()語句


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章