更新時間:2019-10-01 09:00:00 來源:動力節點 瀏覽2940次
今天動力節點java培訓機構小編為大家介紹“ Java面向對象概念和三大特性”,希望通過此大家能夠掌握 Java面向對象概念和三大特性,下面就隨小編一起來了解一下吧。
Java是面向對象的高級編程語言,類和對象是 Java 程序的構成核心。圍繞著 Java 類和 Java 對象,有三大基本特性:封裝是 Java 類的編寫規范、繼承是類與類之間聯系的一種形式、而多態為系統組件或模塊之間解耦提供了解決方案。
本文主要圍繞這三大特性介紹一下 Java 面向對象、組件解耦的核心思想。
1、面向對象思想
面向對象編程是當今主流的程序設計思想,已經取代了過程化程序開發技術,Java 是完全面向對象編程語言,所以必須熟悉面向對象才能夠編寫 Java 程序。
面向對象的程序核心是由對象組成的,每個對象包含著對用戶公開的特定功能和隱藏的實現部分。程序中的很多對象來自 JDK 標準庫,而更多的類需要我們程序員自定義。
從理論上講,只要對象能夠實現業務功能,其具體的實現細節不必特別關心。
面向對象的特點:
(1)面向對象是一種常見的思想,比較符合人們的思考習慣;
(2)面向對象可以將復雜的業務邏輯簡單化,增強代碼復用性;
(3)面向對象具有抽象、封裝、繼承、多態等特性。
面向對象的編程語言主要有:C++、Java、C#等。
2、類和對象的關系
類:對某類事物的普遍一致性特征、功能的抽象、描述和封裝,是構造對象的模版或藍圖,用 Java 編寫的代碼都會在某些類的內部。類之間主要有:依賴、聚合、繼承等關系。
對象:使用 new 關鍵字或反射技術創建的某個類的實例。同一個類的所有對象,都具有相似的數據(比如人的年齡、性別)和行為(比如人的吃飯、睡覺),但是每個對象都保存著自己獨特的狀態,對象狀態會隨著程序的運行而發生改變,需要注意狀態的變化必須通過調用方法來改變,這就是封裝的基本原則。
3、封裝思想
核心思想就是“隱藏細節”、“數據安全”:將對象不需要讓外界訪問的成員變量和方法私有化,只提供符合開發者意愿的公有方法來訪問這些數據和邏輯,保證了數據的安全和程序的穩定。
具體的實現方式就是:
使用 private 修飾符把成員變量設置為私有,防止外部程序直接隨意調用或修改成員變量,然后對外提供 public 的 set 和 get 方法按照開發者的意愿(可以編寫一些業務邏輯代碼,雖然很少這樣做)設置和獲取成員變量的值。
也可以把只在本類內部使用的方法使用 private,這就是封裝的思想,是面向對象最基本的開發規范之一。
在此,我們說一下 Java 的訪問權限修飾關鍵字。Java 中主要有 private、protected、public 和 默認訪問權限四種:
public 修飾符,具有最大的訪問權限,可以訪問任何一個在 CLASSPATH 下的類、接口、異常等。
protected 修飾符,主要作用就是用來保護子類,子類可以訪問這些成員變量和方法,其余類不可以。
default 修飾符,主要是本包的類可以訪問。
private 修飾符,訪問權限僅限于本類內部,在實際開發過程中,大多數的成員變量和方法都是使用 private 修飾的。
Java 的訪問控制是停留在編譯層的,只在編譯時進行訪問權限檢查,不會在類文件中留下痕跡。
通過反射機制,還是可以訪問類的私有成員的。
示例:
public class MobilePhone {
// 使用 private 關鍵字把成員變量私有化
private String os;
private String phoneNumber;
private String brand;
private double dumpEnergy;
// 對外提供訪問、設置成員變量的 public 方法
// 這樣就可以按照我們自己的意愿來訪問、設置成員變量
// 而且也有助于在方法內部對數據有效性進行驗證
public void setOs(String os){
this.os = os;
}
public String getOs(){
return this.os;
}
public void setPhoneNumber(String phoneNumber){
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber(){
return this.phoneNumber;
}
public void setBrand(String brand){
this.brand = brand;
}
public String getBrand(){
return this.brand;
}
public void setDumpEnergy(double dumpEnergy){
this.dumpEnergy = dumpEnergy;
}
public double getDumpEnergy(){
return this.dumpEnergy;
}
// 發短信的方法,不需要做修改
public void sendMessage(String message, String targetPhoneNumber){
System.out.println("發給" + targetPhoneNumber + ", 內容是:" + message);
}
// 充電方法,不需要做修改
public double charge(){
System.out.println("正在充電, 剩余電量:" + dumpEnergy * 100 + "%");
return dumpEnergy;
}
// 對外提供的開機方法
public void startup(){
System.out.println("正在開機......");
// 調用私有開機方法
startup2();
System.out.println("完成開機");
}
// 私有的開機方法,封裝開機細節
private void startup2(){
System.out.println("啟動操作系統......");
System.out.println("加載開機啟動項......");
System.out.println("......");
}
}
在實際的開發過程中,這樣的封裝方式已經成了 Java Bean 代碼編寫的規范。現在主流的框架在使用反射技術為對象賦值、取值時使用的都是 set 和 get 方法,而不是直接操作字段的值。
4、繼承和類實例化過程
(1)在多個不同的類中抽取出共性的數據和邏輯,對這些共性的內容進行封裝一個新的類即父類(也叫做超類或基類),讓之前的類來繼承這個類,那些共性的內容在子類中就不必重復定義,比如 BaseDAO、BaseAction 等。
(2)Java 的繼承機制是單繼承,即一個類只能有一個直接父類。
(3)如果子類和父類有同名成員變量和方法,子類可以使用 super 關鍵字調用父類的成員變量和方法,上述使用方式前提是成員在子類可見。
(4)在調用子類構造方法時,會隱式的調用父類的構造方法 super()。如果父類沒有無參構造方法,為了避免編譯錯誤,需要在子類構造方法中顯式的調用父類的含參構造方法。
(5)子類創建時調用父類構造方法:子類需要使用父類的成員變量和方法,所以就要調用父類構造方法來初始化,之后再進行子類成員變量和方法的初始化。因此,構造方法是無法覆蓋的。
(6)當子類需要擴展父類的某個方法時,可以覆蓋父類方法,但是子類方法訪問權限必須大于或等于父類權限。
(7)繼承提高了程序的復用性、擴展性,也是 Java 語言多態特征的前提。
(8)在實際開發、程序設計過程中,并非先有的父類,而是先有了子類中通用的數據和邏輯,然后再抽取封裝出來的父類。
我們簡單了解下類的實例化過程
(1)JVM 讀取指定 classpath 路徑下的 class 文件,加載到內存,如果有直接父類,也會加載父類;
(2)堆內存分配空間;
(3)執行父類、子類靜態代碼塊;
(4)對象屬性進行默認初始化;
(5)調用構造方法;
(6)在構造方法中,先調用父類構造方法初始化父類數據;
(7)初始化父類數據后,顯示初始化,執行子類的構造代碼塊;
(8)再進行子類構造方法的特定初始化;
(9)初始化完畢后,將地址賦值給引用
為了說明上面的內容,我們來編寫一個簡單的例子。
/*
父類
*/
class Parent {
int num = 5;
static {
System.out.println("父類靜態代碼塊");
System.out.println();
}
{
System.out.println("父類構造代碼塊1," + num);
num = 1;
System.out.println("父類構造代碼塊2," + num);
doSomething();
System.out.println();
}
Parent() {
System.out.println("父類構造方法1," + num);
num = 2;
System.out.println("父類構造方法2," + num);
doSomething();
System.out.println();
}
void doSomething() {
System.out.println("父類doSomething方法1," + num);
num = 3;
System.out.println("父類doSomething方法2," + num);
System.out.println();
}
}
/*
子類
*/
class Child extends Parent {
int num = 10;
/*
靜態代碼塊,在類加載時執行
*/
static {
System.out.println("子類靜態代碼塊");
System.out.println();
}
/*
構造代碼塊
*/
{
System.out.println("子類構造代碼塊1," + num);
num = 11;
System.out.println("子類構造代碼塊2," + num);
doSomething();
System.out.println();
}
Child() {
System.out.println("子類構造方法1," + num);
num = 12;
System.out.println("子類構造方法2," + num);
doSomething();
System.out.println();
}
void doSomething() {
System.out.println("子類doSomething方法1," + num);
num = 13;
System.out.println("子類doSomething方法2," + num);
System.out.println();
}
}
public class A {
public static void main(String[] args) {
Child child = new Child();
child.num = 20;
child.doSomething();
}
}
輸出:
父類靜態代碼塊
子類靜態代碼塊
父類構造代碼塊1,5
父類構造代碼塊2,1
子類doSomething方法1,0
子類doSomething方法2,13
父類構造方法1,1
父類構造方法2,2
子類doSomething方法1,13
子類doSomething方法2,13
子類構造代碼塊1,10
子類構造代碼塊2,11
子類doSomething方法1,11
子類doSomething方法2,13
子類構造方法1,13
子類構造方法2,12
子類doSomething方法1,12
子類doSomething方法2,13
子類doSomething方法1,20
子類doSomething方法2,13
5、多態、反射和組件解耦
多態指允許不同類的對象對同一“消息”做出響應。即同一消息可以根據發送對象的不同而采用多種不同的行為方式。可以用于消除類型之間的耦合關系,Spring 的核心就是多態和面向接口編程。
(1)Java 中可以使用父類、接口變量引用子類、實現類對象;
(2)在這個過程中,會對子類、實現類對象做自動類型提升,其特有功能就無法訪問了,如果需要使用,可以做強制類型轉換。
Java 的反射技術和多態特性是框架開發、組件解耦的核心,在這方面,Spring 的 IOC 和 DI 為我們提供了一個極好的學習范例,Spring 的 IOC 使用反射技術創建、管理對象,DI 使用多態技術為組件注入依賴對象。
在沒有學習 Spring 之前,簡單的解決方案是使用一個 .properties 文件保存程序中使用的接口、實現類類型鍵值信息,然后在程序中使用一個全局 Properties 對象保存這些信息,并且使用反射技術把這些實現類初始化、提供一個靜態的方法獲取指定接口的實現類對象,在組件中就可以使用依賴對象的鍵獲取需要的對象。
這樣的方案帶來的好處就是:當我們需要修改某個組件的實現方式時,比如把之前 JDBC 的 DAO 實現改為 Hibernate 實現,只要把這些新的實現類放到 classpath 下,把 .properties 文件對應接口的實現類類型改成新的 Hibernate 實現類,而不需要修改依賴組件的代碼。
以上就是動力節點java培訓機構小編介紹的“Java面向對象概念和三大特性”的內容,希望對大家有幫助,更多java最新資訊請繼續關注動力節點java培訓機構官網,每天會有精彩內容分享與你。
相關免費視頻教程推薦
java后端開發教程下載——面向對象概念:http://www.dabaquan.cn/xiazai/2649.html
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習