【核心模塊】 面向對象-類與對象、封裝、構造方法

面向對象思想概述

Java語言是一種面向對象的程序設計語言,而面向對象思想是一種程序設計思想,我們在面向對象思想的指引下,使用Java語言去設計、開發計算機程序。 這裡的對象泛指現實中一切事物,每種事物都具備自己的屬性行為。面向對象思想就是在計算機程序設計過程中,參照現實中事物,將事物的屬性特徵、行為特徵抽象出來,描述成計算機事件的設計思想。 它區別於面向過程思想,強調的是通過調用對象的行為來實現功能,而不是自己一步一步的去操作實現。

舉例

洗衣服:

面向過程:把衣服脫下來-->找一個盆-->放點洗衣粉-->加點水-->浸泡10分鐘-->揉一揉-->清洗衣服-->擰乾-->晾起來

面向對象:把衣服脫下來-->打開全自動洗衣機-->扔衣服-->按鈕-->晾起來

區別:

面向過程:強調步驟。

面向對象:強調對象,這裡的對象就是洗衣機

特點

面向對象思想是一種更符合我們思考習慣的思想,它可以將複雜的事情簡單化,並將我們從執行者變成了指揮者。

面向對象的語言中,包含了三大基本特徵,即封裝、繼承和多態。

類和對象

環顧周圍,你會發現很多對象,比如桌子,椅子,同學,老師等。桌椅屬於辦公用品,師生都是人類。那麼什麼是類呢?什麼是對象呢?

什麼是類

:是一組相關屬性行為的集合。可以看成是一類事物的模板,使用事物的屬性特徵和行為特徵來描述該類事物。

現實中,描述一類事物:

屬性:就是該事物的狀態信息。

行為:就是該事物能夠做什麼

舉例:小貓。

屬性:名字、體重、年齡、顏色。

行為:走、跑、叫。

什麼是對象

對象:是一類事物的具體體現。對象是類的一個實例(對象並不是找個女朋友),必然具備該類事物的屬性和行為。

現實中,一類事物的一個實例:一隻小貓。

舉例:一隻小貓。

屬性:tom、5kg、2 years、yellow。

行為:溜牆根走、蹦躂的跑、喵喵叫

類與對象的關係

類是對一類事物的描述,是抽象的

對象是一類事物的實例,是具體的

類是對象的模板,對象是類的實體。


【核心模塊】 面向對象-類與對象、封裝、構造方法

類和對象的關係舉例

類的定義

事物與類的對比

現實世界的一類事物:

屬性:事物的狀態信息。

行為:事物能夠做什麼。

Java中用class描述事物也是如此:

成員變量:對應事物的屬性

成員方法:對應事物的行為

類的定義格式

<code>

public

class

ClassName

{

}/<code>

定義類:就是定義類的成員,包括成員變量成員方法

成員變量:和以前定義變量幾乎是一樣的。只不過位置發生了改變。在類中,方法外

成員方法:和以前定義方法幾乎是一樣的。只不過把static去掉,static的作用在面向對象後面課程中再詳細講解。

類的定義格式舉例:

<code>

public

class

Student

{ String name;

int

age;

publicvoid

study

(

)

{ System.

out

.println(

"好好學習,天天向上"

); }

publicvoid

eat

(

)

{ System.

out

.println(

"學習餓了要吃飯"

); } }/<code>

對象的使用

對象的使用格式

創建對象:

<code>類名 對象名 = 

new

類名();/<code>

使用對象訪問類中的成員:

<code> 對象名.成員變量;
對象名.成員方法();/<code>

對象的使用格式舉例:

<code>

public

 

class

 

Test01_Student

 {  

public

 

static

 

void

 

main

(

String[] args

)

 {   Student s = 

new

 Student();   System.

out

.println(

"s:"

+s);  System.

out

.println(

"姓名:"

+s.name);  System.

out

.println(

"年齡:"

+s.age); System.

out

.println(

"‐‐‐‐‐‐‐‐‐‐"

);   s.name = 

"趙麗穎"

;     s.age = 

18

;    System.

out

.println(

"姓名:"

+s.name);  System.

out

.println(

"年齡:"

+s.age);  System.

out

.println(

"‐‐‐‐‐‐‐‐‐‐"

);     s.study(); s.eat();  }  }/<code>


【核心模塊】 面向對象-類與對象、封裝、構造方法

成員變量默認值

類與對象的練習

定義手機類:

<code>

public

class

Phone

{ String brand;

int

price; String color;

public

void

call

(

String name

)

{ System.

out

.println(

"給"

+name+

"打電話"

); }

public

void

sendMessage

(

)

{ System.

out

.println(

"群發短信"

); } }/<code>

定義測試類:

<code>

public

class

Test02Phone

{

public

static

void

main

(

String[] args

)

{ Phone p =

new

Phone(); System.

out

.println(

"品牌:"

+p.brand); System.

out

.println(

"價格:"

+p.price); System.

out

.println(

"顏色:"

+p.color); System.

out

.println(

"‐‐‐‐‐‐‐‐‐‐‐‐"

); p.brand =

"錘子"

; p.price =

2999

; p.color =

"棕色"

; System.

out

.println(

"品牌:"

+p.brand); System.

out

.println(

"價格:"

+p.price); System.

out

.println(

"顏色:"

+p.color); System.

out

.println(

"‐‐‐‐‐‐‐‐‐‐‐‐"

); p.call(

"紫霞"

); p.sendMessage(); } }/<code>

對象內存圖

一個對象,調用一個方法內存圖


【核心模塊】 面向對象-類與對象、封裝、構造方法

通過上圖,我們可以理解,在棧內存中運行的方法,遵循"先進後出,後進先出"的原則。變量p指向堆內存中的空間,尋找方法信息,去執行該方法。

但是,這裡依然有問題存在。創建多個對象時,如果每個對象內部都保存一份方法信息,這就非常浪費內存了,因為所有對象的方法信息都是一樣的。那麼如何解決這個問題呢?請看如下圖解。

兩個對象,調用同一方法內存圖


【核心模塊】 面向對象-類與對象、封裝、構造方法

一個引用,作為參數傳遞到方法中內存圖


【核心模塊】 面向對象-類與對象、封裝、構造方法

成員變量和局部變量區別

變量根據定義位置的不同,我們給變量起了不同的名字。如下圖所示:


【核心模塊】 面向對象-類與對象、封裝、構造方法

1.在類中的位置不同 重點

成員變量:類中,方法外

局部變量:方法中或者方法聲明上(形式參數)

2.作用範圍不一樣 重點

成員變量:類中

局部變量:方法中

3.初始化值的不同 重點

成員變量:有默認值

局部變量:沒有默認值。必須先定義,賦值,最後使用

4.在內存中的位置不同 瞭解

成員變量:堆內存

局部變量:棧內存

5.生命週期不同 瞭解

成員變量:隨著對象的創建而存在,隨著對象的消失而消失

局部變量:隨著方法的調用而存在,隨著方法的調用完畢而消失

封裝:

封裝概述

面向對象編程語言是對客觀世界的模擬,客觀世界裡成員變量都是隱藏在對象內部的,外界無法直接操作和修改。封裝可以被認為是一個保護屏障,防止該類的代碼和數據被其他類隨意訪問。要訪問該類的數據,必須通過指定的方式。適當的封裝可以讓代碼更容易理解與維護,也加強了代碼的安全性。

原則

屬性隱藏起來,若需要訪問某個屬性,提供公共方法對其訪問。

封裝的步驟

1. 使用 private 關鍵字來修飾成員變量。

2. 對需要訪問的成員變量,提供對應的一對 getXxx 方法 、 setXxx 方法。

封裝的操作——private關鍵字

private的含義

1. private是一個權限修飾符,代表最小權限。

2. 可以修飾成員變量和成員方法。

3. 被private修飾後的成員變量和成員方法,只在本類中才能訪問。

private的使用格式

private 數據類型 變量名 ;

使用 private 修飾成員變量,代碼如下:

<code>

public

class

Student

{

private

String name;

private

int

age; }/<code>

提供 getXxx 方法 / setXxx 方法,可以訪問成員變量,代碼如下:

<code>

public

class

Student

{

private

String name;

private

int

age;

public

void

setName

(String n)

{ name = n; }

public

String

getName

()

{

return

name; }

public

void

setAge

(

int

a)

{ age = a; }

public

int

getAge

()

{

return

age; } }/<code>

封裝優化1——this關鍵字

我們發現 setXxx 方法中的形參名字並不符合見名知意的規定,那麼如果修改與成員變量名一致,是否就見名知意了呢?代碼如下:

<code> 

public

class

Student

{

private

String name;

private

int

age;

public

void

setName

(String name)

{ name = name; }

public

void

setAge

(

int

age)

{ age = age; } }/<code>

經過修改和測試,我們發現新的問題,成員變量賦值失敗了。也就是說,在修改了 setXxx() 的形參變量名後,方

法並沒有給成員變量賦值!這是由於形參變量名與成員變量名重名,導致成員變量名被隱藏,方法中的變量名,無

法訪問到成員變量,從而賦值失敗。所以,我們只能使用this關鍵字,來解決這個重名問題。

this的含義

this代表所在類的當前對象的引用(地址值),即對象自己的引用。

記住 :方法被哪個對象調用,方法中的this就代表那個對象。即誰在調用,this就代表誰。

this使用格式:this.成員變量名;

使用 this 修飾方法中的變量,解決成員變量被隱藏的問題,代碼如下:

<code>

public

class

Student

{

private

String name;

private

int

age;

public

void

setName

(String name)

{

this

.name = name; }

public

String

getName

()

{

return

name; }

public

void

setAge

(

int

age)

{

this

.age = age; }

public

int

getAge

()

{

return

age; } }/<code>

封裝優化2——構造方法

當一個對象被創建時候,構造方法用來初始化該對象,給對象的成員變量賦初始值。

小貼士:無論你與否自定義構造方法,所有的類都有構造方法,因為Java自動提供了一個無參數構造方法,

一旦自己定義了構造方法,Java自動提供的默認無參數構造方法就會失效。

構造方法的定義格式

修飾符 構造方法名(參數列表){

// 方法體

}

構造方法的寫法上,方法名與它所在的類名相同。它沒有返回值,所以不需要返回值類型,甚至不需要void。使用構造方法後,代碼如下:

<code>

public

class

Student

{

private

String name;

private

int

age;

public

Student

()

{}

public

Student

(String name,

int

age)

{

this

.name = name;

this

.age = age; } }/<code>

注意事項

1. 如果你不提供構造方法,系統會給出無參數構造方法。

2. 如果你提供了構造方法,系統將不再提供無參數構造方法。

3. 構造方法是可以重載的,既可以定義參數,也可以不定義參數。

標準代碼——JavaBean

JavaBean 是 Java語言編寫類的一種標準規範。符合 JavaBean 的類,要求類必須是具體的和公共的,並且具有無參數的構造方法,提供用來操作成員變量的 set 和 get 方法。

<code>

public

class

ClassName

{

}/<code>

編寫符合 JavaBean 規範的類,以學生類為例,標準代碼如下:

<code>

public

class

Student

{

private

String name;

private

int

age;

public

Student

()

{}

public

Student

(String name,

int

age)

{

this

.name = name;

this

.age = age; }

publicvoid

setName

(String name)

{

this

.name = name; }

public

String

getName

()

{

return

name; }

public

void

setAge

(

int

age)

{

this

.age = age; }

public

int

getAge

()

{

return

age; } }/<code>

測試類,代碼如下:

<code>

public

class

TestStudent

{

public

static

void

main

(

String[] args

)

{ Student s=

new

Student(); s.setName(

"柳巖"

); s.setAge(

18

); System.

out

.println(s.getName()+

"‐‐‐"

+s.getAge()); Student s2=

new

Student(

"趙麗穎"

,

18

); System.

out

.println(s2.getName()+

"‐‐‐"

+s2.getAge()); } }/<code>


分享到:


相關文章: