課程3A的內容主要是介紹面向對象編程思想的一些基本概念並做了相應的練習指導。 面向對象的思想在當今的軟體開發中占據著主導地位。 Java是一門完全面向對象的語言,是一種天然的分散式互聯網軟體的開發語言,在當今企業級應用中占據絕對領先地位,也是開源世界的頂梁柱。 ...
課程3A-面向對象編程(上)
概述
- 面向對象的思想在當今的軟體開發中占據著主導地位。
- Java是一門完全面向對象的語言,是一種天然的分散式互聯網軟體的開發語言,在當今企業級應用中占據絕對領先地位,也是開源世界的頂梁柱。
- 課程3A的內容主要是介紹面向對象編程思想的一些基本概念。
Warm-Up:準備活動
練習定義方法,調用方法。這個練習首先修改了MainActivity.java中的display()方法的名字,然後修複代碼中的語法錯誤:修改之前所有對於display()方法的調用為當前的方法名。這個練習的目的主要是想讓學生熟悉方法定義和調用的過程以及這兩者之間的一一對應的關係。
在 Android Studio 中打開方法聲明的鍵盤快捷鍵為:Mac:command+b,Windows:control + b。
- 定義一個方法的需要哪些部分?
a) Access Modifier(Accessibility Specifier),訪問控制修飾符。經常使用的是"private"與"public",當使用前者時,表明此方法是私有方法,只能在當前類的上下文(在這裡,即為MainActivity)中被調用;當使用後者時,表明當前方法具有全局的可訪問性,即在代碼中的任何位置都可以調用。
b) Return Data Type,返回值類型。這部分指定當前方法的返回值類型。
c) Method Name,方法名稱。與我們之前使用變數名來引用一個變數類似,我們也可以使用方法名(和傳入參數)來調用定義好的方法。
d) Matched Parentheses,匹配的圓括弧。匹配的圓括弧中的是實參列表(聲明或定義方法時)與形參列表(調用方法時),調用方法時,必須要有匹配的圓括弧,否則編譯時會提示語法錯誤。
e) Parameter List,參數列表,以逗號分隔,實參列表中的變數名可以在整個當前函數的範圍內使用,出了該範圍,這些變數都不可以再被引用。形參列表中的傳入參數需要具有相同或者是相容的類型(以便編譯器能夠自動進行隱式類型轉換),變數名不必與對應的實參變數相同。
f) Matched Curly Braces,匹配的花括弧,表示當前函數的範圍。
g) Method Signature,方法簽名。方法簽名由方法名、參數列表構成。Method Signature與方法重載的概念緊密相關:只有具有不同方法簽名的方法能夠同時存在於一個上下文中,僅僅只是返回值類型不同的方法不能夠重載。
使用方法的流程: 確定方法簽名以及返回值類型,作為方法的聲明 ----> 在成對的花括弧代表的語句塊中實現當前方法的邏輯 ----> 在需要的地方調用方法 ----> 如果需要利用被調方法的返回值,則對該返回值進行處理。
進行了以上練習後,JustJava程式在手機上運行的效果如圖1所示。
Android項目的資源文件
資源文件包括圖片、音頻、XML文件(佈局和項目配置)、字元串文件等等。
使用資源文件可以將程式的邏輯與程式具體展現形式分離開來。比如想要做APP的國際化時,就可以在各個語言各自的字元串文件之間切換, 非常方便;想要適應高清屏幕時,只需載入同一資源(圖像、視頻)的更高清版本。
另一方面,Java代碼負責程式邏輯的實現,與資源文件之間是松耦合的關係,提升了代碼及資源文件的復用性。如果把資源都硬編碼在代碼中,整個項目會顯得比較混亂,不利於縮短開發周期,也不利於項目的維護和迭代。
在使用Java來開發Android項目時,會生成一個R.java文件,其中對res資源文件中的資源進行了編號,方便在Java代碼中訪問這些資源。對於string字元串類型的資源,訪問的語法為R.string.* (“*”即為對應的資源文件名);對於layout佈局類型的資源,訪問的語法為R.layout.*。
在Java文件與xml文件中都可以訪問資源文件,具體方式如圖2所示。
圖2. 訪問Android項目資源文件
對象、類、繼承
- 當在onCreate()方法中調用setContentView()方法時,
setContentView(R.layout.activity_main);
我們通過R這個對當前所有的項目資源的抽象的類來訪問佈局資源activity_main.xml,Android程式執行到這一語句時會解析此xml文件,分析各個Views之間的層級關係並據此生成對應的Java對象。
Java對象:可以擁有成員(變數或方法),其整體是對State的封裝,外界(凡是無法直接訪問此對象內部的,對於該對象而言都可稱為“外界”)可以使用此對象提供的一些方法(比如說,setter方法與getter方法)來修改其成員變數,從而改變此對象的狀態。外界可能根據對象狀態的改變進而採取不同的操作,實現期望的邏輯。
- Java類
- member variable == field == state,成員變數、域、狀態等術語在當前語境(Java Class)下的含義相同。
- 成員變數的命名規範(naming conventions):成員變數的名字以"m"或者"m_"作為首碼。
- 與之前說過的定義變數類似,定義一個Java Class時,也需要指定(不指定的話,我記得訪問控制預設是protected級別的)當前類的訪問控制修飾符(Acess Modifier)。
- Constructor,構造函數。構造函數是為了實例化(instantiate)Java類為一個實際存在於記憶體中的對象,構造函數與普通函數類似,也有參數列表;定義構造函數與定義普通函數的過程類似,但不需要指定返回值類型,其語法格式為“類名 + 參數列表 + 實現類實例化的代碼塊”。
- 如果一個類的定義中沒有顯式地指定任何構造函數,那麼實例化該類時對調用預設構造函數。 需要註意區別無參構造函數預設(default,預設的)構造函數:當一個類的定義中顯式地定義了一個不接受任何參數的構造函數時,那麼在不傳入參數地實例化這個類時,調用的就是無參構造函數,而不是預設(預設)構造函數。
- Factory Method,工廠方法。除了使用構造函數來創建對象,我們也可以使用工廠方法。更詳細地來講,工廠方法是一種對象創建型的設計模式,其意圖在於定義一個用於創建對象的介面,讓子類決定實例化哪一個類;效果就是一個類的實例化被延遲到其子類。
6.1 Factory Method的適用範圍: 當一個類不知道它所必須創建的對象的類的時候;當一個類希望由它的子類來指定它所創建的對象的時候;當類將創建對象的職責委托給多個Helper子類中的某一個,且你希望將哪一個Helper子類是代理者這一信息局部化的時候。 如下的代碼即應用Factory Method把Toast類的實例化延遲了:等待有具體文本信息的時候再實例化出Toast對象。
Toast toast = Toast.makeText(context, text, duration);
註意,在一個class內部與外調用方法的區別: a)class之外無法訪問private方法;b)語法上的區別。類中調用方法可以不指定當前對象(this),而在類外調用則必須指定。如圖3所示。
圖3. 在類的內部與外部調用類方法的區別
Object Method,對象方法。 通過調用對象方法(object method)在Java代碼中改變Views的屬性,使得我們可以運行時根據用戶的交互,動態地改變Views的外觀。這對於互動式的APP來說十分重要。
Inheritance,繼承。當一個類A繼承另一個類B時,預設地,A就會擁有B的所有public方法與成員(無法繼承private的方法與成員變數)。子類可以復用繼承而來的方法、變數,也可以重寫(override)父類的方法。 通過繼承,可以實現多態性,使得程式設計更加靈活、強大。繼承是OOP(Object Oriented Programming,面向對象編程)中非常重要的一環;用類圖可以展現整個軟體系統的繼承層次關係,現代軟體項目的設計基本上沒有脫離了類圖的。
Casting,轉型。 方法findViewById()返回的對象類型是View;但如果傳入的id是一個View的子類的id,為了正確使用該方法的返回值,我們需要進行轉型,將findViewById()的返回值轉型成為該id對應的實際的對象類型(可以通過查看xml源文件來得到該信息)。關於Java中轉型的更多知識,可以參考 ORACLE官方文檔_Inheritance (請參閱“Casting Objects”部分)。