淺談面向對象

編程語言有面向過程的也有面向對象的。像我們學習的C語言就是面向過程的語言,C++、Java等就是面向對象的語言。
可能很多人都聽過面向過程,面向對象。那麼到底什麼是面向過程,什麼又是面向對象呢?
面向過程,是一種以過程爲中心的編程思想,就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了。
面向對象,是一種以事物爲中心的編程思想,是把構成問題事務分解成各個對象,建立對象的目的不是爲了完成一個步驟,而是爲了描敘某個事物在整個解決問題的步驟中的行爲。與面向過程明顯不同的就是封裝、繼承、類。
學習Java語言就要學習面向對象的編程思想,掌握封裝、繼承、多態、類等。

簡單來說,面向對象的思想就是,將我們實現某個方法或者功能的代碼進行封裝,封裝的好處就是,結構清晰,當我們用到該方法或者功能的時候直接找到對應的類就好了。

面向對象的思想有其明顯的特點:

  • 面向對象的思想是一種更爲符合人類思維方式的思想
  • 可以將複雜的事情簡單化
  • 很大程度上,減輕了編程者的編程負擔

面向對象的特徵是:

  • 封裝
  • 繼承
  • 多態

Java語言中最基本的單位就是類,所以萬事萬物都可以用類來進行表示。
那麼什麼是呢?
類是一組屬性和方法(功能)的集合。屬性是事物的描述信息,方法則是事物的行爲。
我們將類中的屬性和方法稱爲成員屬性和成員方法。定義類說白了就是定義類中的成員屬性和成員方法。

那麼什麼是對象呢?
對象就是類的實例(類的具體體現)。由於類是一組事物相同或相似的屬性和行爲的概括和抽象,所以我們不能直接使用類中的成員屬性和成員方法。若要使用,我們就要創建類的實例即對象來使用。

如何定義類呢?
class 類名{
成員屬性;
成員方法;
}
舉例:
在這裏插入圖片描述
學會了定義類後,就可以創建對象來使用類的成員了。
對象的創建
類名 對象名 = new 類名();

成員變量的使用
對象名.成員變量

成員方法的使用
對象名.成員方法( . . .)
舉例:
在這裏插入圖片描述
以上述例子爲例,簡述一下創建對象這個過程在內存中的流程。
在這裏插入圖片描述

在這裏插入圖片描述

談到對象這個概念時,有一個概念叫匿名對象。我們一般創建對象時都是 類名 對象名 = new 類名();這樣的形式,實際上我們以這樣的方式創建對象時是給對象起了一個名字。那麼匿名對象就是我們在創建對象的時候沒有給他起名字,即直接以 new 類名();的方式創建的對象。
匿名對象使用的次數不是很多,也不是特別常用。可以在以下場景中使用匿名對象:

  • 當我們調用方法,且僅調用一次時可以使用匿名對象,匿名對象可以當做實際參數進行傳遞。

舉例:
在這裏插入圖片描述

在類中,有成員屬性(成員變量)和成員方法。那麼類中的成員變量和局部變量有什麼區別呢?

  • 首先,兩者在類中的位置不同,成員變量是在類中方法外;而局部變量是定義在方法內或者是方法聲明中
  • 其次,兩者的生存週期不同,成員變量是隨着類的調用或者對象的創建而產生,隨着對象的消失而消失;局部變量是隨着方法的調用而產生,隨着方法的調用完畢而消失
  • 然後,兩者在內存中的位置不同,成員變量是在堆內存中;局部變量在棧內存中
  • 最後,兩者的初始化值不同,成員變量有默認的初始化值,若爲int類型,則默認初始化值爲0,若爲float,double,則爲0.0,若爲char,則爲空格字符;局部變量沒有默認的初始化值,所以必須定義賦值後才能使用

當類的成員變量名和局部變量名重名時,在使用原則上採取的是就近原則

之前談到過方法的調用問題,方法的形參一般有兩種類型:

  • 基本類型,傳的是,即形參的值的改變不影響實參的值,這樣的調用方式可以成爲值傳遞
  • 引用類型,傳的是引用,即形參的值的改變會影響實參的值,這樣的調用方式可以成爲引用傳遞

當方法的形參的類型是 類型的時候,這個時候需要傳的是該類的對象。

構造方法

什麼是構造方法?
構造方法是在創建對象的時候,給對象的成員進行初始化的。

構造方法的特點:

  • 方法名與類名相同
  • 沒有返回值類型
  • 沒有具體的返回值

舉例:
在這裏插入圖片描述
有的人可能會想到,既然構造方法是用來初始化對象的,那麼可以在創建對象的時候,就對對象的成員變量進行賦值操作嗎?
當然可以了,此時就需要進行構造方法的重載了。
舉例:
在這裏插入圖片描述
需要注意的是:

  • 如果我們沒有自己在類中定義構造方法,系統會默認給我們提供一個無參構造方法
  • 如果我們自己在類中定義了構造方法,那麼系統不會給我們提供無參構造方法。創建對象時只會調用我們自己的構造方法。
  • 如果我們自己在類中定義了構造方法,還想使用無參構造方法時,就需要自己定義無參構造方法。最好就是每次定義類時,自己定義無參構造方法。

總結一下創建對象(Student student = new Student())都做了哪些事情:

  1. 首先將該類對應的class文件(Student.class)加載進內存的方法區
  2. 在棧內存中爲該類對象對應的變量(student)開闢內存空間
  3. 在堆內存爲該類的對象(new Student())開闢內存空間
  4. 對對象的成員變量進行默認的初始化
  5. 對對象的成員變量進行顯式初始化
  6. 通過構造方法對對象的成員變量進行賦值
  7. 對象初始化完畢後,將該內存的地址值賦給變量(student)

封裝

何爲封裝?
封裝就是隱藏對象的屬性和實現細節,只提供對外公共訪問的方式。

封裝的優點:

  • 隱藏了實現細節,提供了公共訪問方式
  • 提高了代碼的複用性
  • 提高了代碼的可維護性
  • 提高了程序的安全性

封裝的原則:

  • 可以將不需要對外提供的內容隱藏起來,如屬性
  • 對外只提供可以公共訪問的方法

那麼,問題來了,我們如何做到將不需要對外提供的內容隱藏起來呢,一般來說在類中我們只需將屬性隱藏起來。這個時候,我們可以使用Java中的private關鍵字。

private
private:私有的,是一個權限修飾符。
private可以修飾成員變量和成員方法,被修飾的成員只能在本類中被訪問。

這樣使用private關鍵字,我們就可以實現封裝的目的。但存在一個問題就是,我們的成員變量無法直接訪問進行賦值、輸出等操作,所以還需要在類中提供成員變量對應的get和set方法來間接訪問成員變量。

一般而言,對於成員變量xxx,對應一個getXxx()和setXxx()方法。set方法用來進行賦值操作,get方法用來獲取成員變量值。
舉例:
在這裏插入圖片描述
this
在上述例子中,set方法裏,有一個關鍵字this。那麼爲什麼會有this關鍵字呢?
在類的成員方法中,若方法的局部變量和類的成員變量同名且需要在方法中用到兩個變量時就需要使用this關鍵字來說明該關鍵字後的變量是成員變量。如果不使用該關鍵字就會出現一個現象:局部變量隱藏成員變量(就近原則)即兩個變量都是局部變量。

this可以理解爲當前類的對象引用。簡單來說就是它代表當前類的一個對象。誰調用這個方法,那麼該方法的內部的this就代表誰。
使用this就可以解決局部變量隱藏成員變量的問題。

至此,我們可以通過兩種方式來進行類的對象的成員變量的初始化和賦值操作:

  • 通過構造方法,即在創建對象時,就進行賦值操作。
  • 通過set方法。
    在這裏插入圖片描述

static
在創建好幾個對象時,有的時候對象的某個屬性的值是一樣的,除了可以在類中將成員變量的值直接賦值爲對應的值外,還有一個方法就是使用static關鍵字。
static:靜態的,它是一個狀態修飾符。
由它修飾的變量是存儲在方法區的靜態區的,且該變量是共享的變量。

具體來說static關鍵字的特點

  • 它是隨着類的加載而加載的
  • 它是優先於對象存在的(對象是要創建纔會存在)
  • 它是被類的所有對象所共享的(該變量只有一份,在內存中只給它開闢一份內存空間)
  • 不同於成員變量,它可以通過類名調用(且最好使用類名調用)也可通過對象名調用。在類中由static修飾的成員,我們一般稱之爲類成員。

在使用static關鍵字時也需要注意以下幾點:

  • static中不能出現this關鍵字。
    原因:static是隨着類的加載而加載的,而this是創建對象後纔可以用的,又由於,靜態是先於對象存在的,一個存在的事物怎麼可以使用不存在的事物呢?
  • 靜態方法只能訪問靜態的成員和靜態的方法,不能訪問非靜態的成員和方法;但是非靜態的即可以訪問非靜態的,也可以訪問靜態的。

static是一個狀態修飾符,可以修飾變量,被static修飾的變量稱爲靜態變量,那麼靜態變量和成員變量有什麼區別呢?

  • 首先,兩者所屬不同。靜態變量是屬於類的,也稱爲類變量;成員變量是屬於對象的,也稱爲實例變量。
  • 其次,兩者在內存位置不同。靜態變量是存儲在方法區的靜態區;成員變量是存儲在堆內存。
  • 然後,兩者生存週期不同。靜態變量是隨着類的加載而加載,隨着類的消失而消失;成員變量是隨着對象的創建而產生,隨着對象的消失而消失。
  • 最後,兩者的調用方式不同。靜態變量是用類名或對象名來調用,但一般使用類名調用;成員變量是隻能用對象名來調用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章