五、面向對象
1.面向對象與面向過程:
面向過程,強調的是功能行爲;面向對象,將功能封裝進對象,強調具備了功能的對象。
2.面向對象的三大特性:封裝、繼承、多態
3.java類及類的成員:
Java代碼世界是由諸多個不同功能的類構成的,一個類class一般包含:
①屬性-成員變量
②行爲-(成員)方法、函數
4.理解:
類 = 汽車設計圖;
對象 = 實實在在的汽車
面向對象程序設計的重點是類的設計
定義類其實是定義類中的成員(成員變量和成員方法)
5.類的語法格式:
修飾符 class 類名 {
屬性聲明;
方法聲明;
}
//方法中不能再定義方法
舉例:
public class Person {
//屬性,成員變量,類的成員變量可以先聲明,不用初始化,類成員變量是有默認值
public String name; //姓名,String的默認值是null
private int age; //年齡,int的默認值是0
public static String sex = "男"; //類變量-後面詳解
//行爲,方法,也叫函數
public void showName(){ //方法的名稱如果是多個單詞,首個的單詞的首字母小寫,其他的單詞首字母大寫,這樣就像一個駝峯一樣,所有叫駝峯命名法
System.out.println("姓名:" + name);
getAge(); //同一個類中,所有的方法可以直接互相調用,不用new去實例化對象
}
//有返回值的函數
public int getAge(){
return age;
}
}
6.類的實例化:對象的創建和使用
①使用new +構造器創建一個新的對象;
②使用“對象名.對象成員”的方式訪問對象成員(包括屬性和方法;
以上面創建的Person類爲例:
public class People {
public static void main(String[] args){
//實例化Person類,也就是創建Person對象
Person person = new Person();
//聲明一個Person類型的變量,變量名person,實例化Person類並且給person賦值,賦值的值就是當前的實例
person.name = "張三"; //給person對象的name屬性賦值
person.showName(); //對象的方法的調用
int i = person.getAge();
System.out.println(i);
person.age = 11; //給person對象的age屬性賦值
int a = person.getAge();
System.out.println(a);
}
}
注:如果創建了一個類的多個對象,對於類中定義的屬性,每個對象都擁有各自的一套副本,且互不干擾.
7.類的成員之一:屬性
(1)語法格式:
修飾符 類型 屬性名 =初值 ;
說明:修飾符private:該屬性只能由該類的方法訪問,不能通過 對象.屬性 的方式調用。
修飾符public:該屬性可以被該類以外的方法訪問。
類型:任何基本類型,如int、boolean或任何類。
(2)變量的分類:
①成員變量:
a.實例變量(不以static修飾):
就是在類實例化成對象之後才能被使用的變量,如Person中的name(成員變量有默認的init值).
實例變量存在於對象所在的堆內存中。
b.類變量(以static修飾):
這樣的變量是靜態的,類不需要實例化成對象就可以通過 類名.屬性 調用.如Person中的sex.
②局部變量:
a.形參(方法簽名中定義的變量)
b.方法局部變量(在方法內定義的變量)
c.代碼塊局部變量(在代碼塊中定義的變量)
③ 注 釋 :
a.局部變量存在於棧內存中,作用的範圍結束,變量空間會自動釋放.
b.局部變量沒有默認初始化值,每次必須顯式初始化.
c.局部變量聲明時不指定權限修飾符
8.類的成員之二:方法
(1)語法格式:
修飾符 返回值類型 方法名(參數類型 形參1,參數類型 形參2,...){
程序代碼
return 返回值;
}
說明: 修飾符:public, private, protected等。
返回類型爲void,則不用return.關於形參,實參,返回值等不再記錄,和C++完全一致
(2) 方 法:
01.方法是類或對象行爲特徵的抽象,也稱爲函數.
02.Java裏的方法不能獨立存在,所有的方法必須定義在類裏.
03.方法只有被調用纔會被執行.
04.方法中只能調用方法,不可以在方法內部定義方法.
並且在同一個類中,方法之間可以直接互相調用,所以在方法中調用另一個方法時不需要new
9.關於對象:
01.匿名對象:不定義對象的句柄,而直接調用這個對象的方法,這樣的對象叫做匿名對象。
使用情況:如果對一個對象只需要進行一次方法調用,那麼就可以使用匿名對象。
經常將匿名對象作爲實參傳遞給一個方法調用。
如: new Person().shout();
02.在一個類中的訪問機制:
類中的方法可以直接訪問類中的成員變量。
(例外:static方法訪問非static的成員變量,編譯不通過.)
03.在不同類中的訪問機制:
先創建要訪問類的對象,再用對象訪問類中定義的成員。
10.方法的重載
01.概念:
在同一個類中,允許存在一個以上的同名方法,只要它們的參數個數或者參數類型不同即可,與形參名無關。
02.代碼示例:
public int add(int x, int y){
return x + y;
}
public double add(int x, double y){
return x + y;
}
public int add(int x, int y, int z){
return x + y + z;
}
//在主類Text中定義重載函數,在main()中,進行對象實例化,以及方法的調用
Text examp = new Text();
examp.add(1, 2);
examp.add(1, 0.5);
examp.add(1,2,3);
03.特點:
與返回值類型無關,只看參數列表,且參數列表必須不同。
參數個數或參數類型,參數相同只是順序不同也可以構成重載
調用時,根據方法參數列表的不同來區別。
在主類Text中定義重載函數,在main()中,
Text examp = new Text();
examp.add(1, 2);
examp.add(1, 0.5);
examp.add(1,2,3);
11.方法--可變個數的形參
定義方法:
a.使用數組作爲形參
(傳參使用時需要在main函數中new一個數組作爲實參傳入,數組長度可變0~+無窮)
public void printInfo(String[] args){
//這裏的String可以根據需要使用基本數據類型
for(int i = 0; i < args.length; i++){
System.out.println(args[i]);
}
}
b.使用Java自帶的可變形參表示法(使用方法與使用數組的形式相同)
//方法的參數部分有可變形參,需要放在形參聲明的最後
public void printInfo1(int d, String... args){
for(int i = 0; i < args.length; i++){
System.out.println(args[i]);
}
}
//使用:(在此之前要在main中實例化一個方法所在的類,命名爲p3)
p3.printInfo1(2,"lisi", "23", "男");
//或者像使用數組一樣
String[] ss2 = new String[]{"北京市xxx","13133334444","152109874523666541"};
p3.printInfo1(ss2);
//不同的是,當參數爲空時,使用數組的方法要傳入null或空數組,用b方法形參可以空着
12.JVM的內存模型
13.方法--參數傳遞
01.Java裏方法的參數傳遞方式只有一種:值傳遞。
即將實際參數值的副本(複製品)傳入方法內,而參數本身不受影響。
02.參數傳遞的兩種情況
a.如果方法的形參是基本數據類型,那麼實參(實際的數據)向形參傳遞參數時,就是直接傳遞值,把實參的值複製給形參。
b.如果方法的形參是對象,那麼實參(實際的對象),向形參傳遞參數的時,也是把值給形參,這個值是實參在棧內存中的值,也就是引用對象在堆內存中的地址。
基本數據類型都是保存在棧內存中,引用對象在棧內存中保存的是引用對象的地址,那麼方法的參數傳遞是傳遞值(是變量在棧內存的當中的值)
03.參數傳遞的內存示意圖
14.源文件佈局:
[<包聲明>]
[<引用聲明>]
<類聲明>
15.關鍵字-package
01.package語句作爲Java源文件的第一條語句,指明該文件中定義的類所在的包。若缺省該語句,則指定爲無名包.
02.包對應於文件系統的目錄,package語句中,用 “.” 來指明包(目錄)的層次.
03.包通常用小寫單詞,類名首字母通常大寫.
16.關鍵字-import
01.作用:爲使用定義在不同包中的Java類,需用import語句來引入指定包層次下所需要的類或全部類(.*),但是包內的子包中的類不會被引用。
02.語法格式:import 包名[.子包名…]. <類名 |*>
03.代碼示例:
import p1.Test; //import p1.*;表示引入p1包中的所有類
public class TestPackage{
public static void main(String args[]){
Test t = new Test(); //Test類在p1包中定義
t.display();
}
}
04.import語句出現在package語句之後、類定義之前,一個源文件中可包含多個import語句。
17.面向對象特徵之一:封裝和隱藏
使用者對類內部定義的屬性(對象的成員變量)的直接操作會導致數據的錯誤、混亂或安全性問題
01.Java中通過將數據聲明爲私有的(private),再提供公共的(public)方法:
getXxx()和setXxx()實現對該屬性的操作,以實現下述目的:
a.隱藏一個類中不需要對外提供的實現細節;
b.使用者只能通過事先定製好的方法來訪問數據,可以方便地加入控制邏輯,限制對屬性的不合理操作;
c.便於修改,增強代碼的可維護性;
02.四種訪問權限修飾符
03. 注意:
a.對於class的權限修飾只可以用public和default(缺省)。
b.public類可以在任意地方被訪問。
c.default類只可以被同一個包內部的類訪問。
d.在同一個Java文件中可以寫多個class,但是隻有一個可以定義爲public,其他修飾符空着(default)。
18.類的成員之三:構造器(構造函數)
01.構造器的特徵
a.它具有與類相同的名稱
b.它不聲明返回值類型。(與聲明爲void不同)
c.不能被static、final、synchronized、abstract、native修飾,不能有return語句返回值
02.構造器的作用:創建對象;給對象進行初始化
a.如:Order o = new Order(); Person p = new Person(Peter,15);
b.New對象實際就是調用類的構造方法(構造函數-C++後遺症)
03.語法格式:
修飾符 類名 (參數列表) { //修飾符與類的修飾符一致
初始化語句; //可以使用初始化語句和參數列表將類的屬性默認初始化或顯式初始化
}
04.根據參數不同,構造器可以分爲如下兩類:
a.隱式無參構造器(系統默認提供)
b.顯式定義一個或多個構造器(無參、有參)
05.注 意:
a.Java語言中,每個類都至少有一個構造器
b.默認構造器的修飾符與所屬類的修飾符一致
c.一旦顯式定義了構造器,則系統不再提供默認構造器
d.一個類可以創建多個重載的構造器
e.父類的構造器不可被子類繼承
19.構造器重載(構造函數重載)
01.構造器重載使得對象的創建更加靈活,方便創建各種不同的對象。
02.構造器重載舉例:
public class Person{
public Person(String name, int age, Date d) {this(name,age);…}
public Person(String name, int age) {…}
public Person(String name, Date d) {…}
public Person(){…}
}
03.構造器重載,參數列表必須不同
20.關鍵字—this
01.它在方法內部使用,即表示這個方法所屬對象的引用;
02.它在構造器內部使用,表示該構造器正在初始化的對象。
03. this表示當前對象,可以調用類的屬性、方法和構造器。
04.使用時機:當在方法內需要用到調用該方法的對象時,就用this。
05.使用this,調用屬性、方法。代碼示例:
class Person{ // 定義Person類
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ; //這裏必須用this指針表明name爲類的屬性,而非形參
this.age = age ; }
public void getInfo(){
System.out.println("姓名:" + name) ;
this.speak();
}
public void speak(){
System.out.println(“年齡:” + this.age);
}
}
/**
* a.當形參與成員變量重名時,如果在方法內部需要使用成員變量,
* 必須添加this來表明該變量時類成員
* b.在任意方法內,如果使用當前類的成員變量或成員方法可以在其前面添加this,
* 增強程序的閱讀性
*/
class Person{ // 定義Person類
private String name ;
private int age ;
public Person(){ // 無參構造
System.out.println("新對象實例化") ;
}
public Person(String name){
this(); // 調用本類中的無參構造方法,且放在構造方法的首行
this.name = name ;
}
public Person(String name,int age){
this(name) ; // 調用有一個參數的構造方法,且放在構造方法的首行
this.age = age;
}
public String getInfo(){
return "姓名:" + name + ",年齡:" + age ;
}
}
/**
* c.this可以作爲一個類中,構造器相互調用的特殊格式
* d.使用this()必須放在構造器的首行
* e.使用this調用本類中其他的構造器,保證至少有一個構造器是不用this的。
*(實際上就是不能出現構造器自己調用自己)
*/
21.JavaBean
01.JavaBean是一種Java語言寫成的可重用組件
02.所謂javaBean,是指符合如下標準的Java類:
a.類是公共的
b.有一個無參的公共的構造器
c.有屬性,屬性一般是私有的,且有對應的get、set方法
03.用戶可以認爲JavaBean提供了一種隨時隨地的複製和粘貼的功能,而不用關心任何改變。
04.對於eclipse,在創建了類和其中的屬性後,可以使用 右鍵 -> Source -> Generate Geeters and Setters,進行設置,直接 生成類中各個屬性的setter和getter.