面向對象思想概述
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
StringgetName
()
{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
StringgetName
()
{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
StringgetName
()
{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>