方法(C語言中稱爲函數)
方法:由多條語句組成,可以重複使用的,完成一個或多個功能的代碼集合;方法只能聲明在類中,不能聲明在其他方法中語法格式:
[訪問修飾符] 返回值類型 方法名([參數列表]){
//代碼塊
}
注:這裏的中括號[]代表括號裏的內容可以寫也可以不寫,如果寫,中括號不用寫
例如:
/**
* 演示方法的聲明和調用
* @author 學霸聯盟 - 趙燦
*/
public class MethodDeclareDemo {
/**
* 聲明瞭一個沒有參數的方法,方法名爲m1
* 方法體也是空的,表示這個方法什麼都沒做
*/
void m1(){}
/**
* 聲明瞭一個帶兩個參數的方法,方法名爲m2
* 這裏的兩個參數,本質就是聲明變量,稱爲形式參數,簡稱形參
* 當這個方法被調用時,按照形參的順序,傳入對應數據類型的值或變量
* 被傳入的值稱爲實際參數,簡稱形參
* 該方法的方法體中有一條輸出語句,輸出傳入兩個參數的值,這就是方法的功能
*/
void m2(String name, int age){
System.out.println("姓名:" + name + " 年齡:" + age);
}
/**
* 這也是一個方法,方法名是main,有一個String[]類型的參數
* 只不過這個方法比較特殊,是程序的入口
*/
public static void main(String[] args){
//創建一個MethodDeclareDemo類的對象
MethodDeclareDemo mdd = new MethodDeclareDemo();
//調用方法m1,m1這個方法什麼都沒有做
mdd.m1();
/*
* 調用方法m2,由於m2聲明瞭參數,調用時必須傳入實參
* "張三"和18就是傳遞給方法m2的實參
* 參數傳遞過程相當於賦值操作
* 程序執行mdd.m2("張三", 18);這條語句時
* 會將"張三"賦值給形參name(相當於String name = "張三")
* 18賦值給形參age(相當於int age = 18)
*/
mdd.m2("張三", 18);
}
}
運行結果:姓名:張三 年齡:18
方法的參數:就是在方法的小括號中聲明的變量,這個變量稱爲:形式參數,簡稱:形參;用於接收調用時傳入的值(實參),形參的使用範圍是整個方法,多個參數中間用英文格式的逗號隔開;當帶有參數的方法被調用時,必須對應方法聲明時編寫的參數類型和順序,給這個方法傳入實際的值;這個實際值稱爲實際參數(簡稱:實參);返回值類型:必須寫,如果一個方法不需要返回值,返回值類型寫void
返回值:方法執行完畢後,返回給調用者的結果;使用關鍵字return返回,並且返回的值要和返回值類型匹配;格式:return 返回值;
關鍵字return:用在方法中,作用是結束整個方法;
例如:某人要去手機店買一部手機,那麼他需要先給錢,然後獲得手機。其中給的錢就是實參,手機就是返回值
實例:
/**
* 樣式方法的返回值類型和返回值
* @author 學霸聯盟 - 趙燦
*/
public class Person {
/*
* 聲明一個方法名爲buy的方法,有一個類型爲double的形式參數money
* 返回值的類型是String,那麼在方法中必須使用關鍵字return,返回一個String類型的值
*/
String buy(double money) {
// 聲明String類型的變量phone
String phone;
// 判斷傳入的錢是否大於6000
if (money > 6000) {
// 如果大於6000,就給變量phone賦值爲“蘋果手機”
phone = "蘋果手機";
} else {
// 如果不大於6000,就給變量phone賦值爲“華爲手機”
phone = "華爲手機";
}
/*
* 因爲當程序執行到方法調用語句時,程序會跳轉到被調用的方法中執行
* 當方法被執行完之後,又會返回到方法調用語句處
* 所以方法中使用關鍵字return返回的結果被稱爲返回值
* 當方法聲明的返回值類型不是void時,方法中必須使用return語句返回一個返回值
* 此處phone就是返回值
*/
return phone;
}
/*
* 聲明一個不帶參數的方法,方法名爲call
* 聲明返回值類型爲void代表這個方法沒有返回值
* 方法中也可以寫return語句,也可以不寫
* 如果寫return後面只能跟英文格式的分號; 即:return;
*/
void call() {
/*
* 此處聲明一個String類型的變量myPhone,來接收buy方法的返回值
* 因爲buy的返回值類型是String,所有此處用String類型的變量接收
* 相當於String myPhone = phone(buy方法中return後面的phone)
* 當程序執行buy(1000.0);語句調用buy方法時,程序會跳到buy方法中執行
* 直到遇到buy方法中的return語句後
* 再返回到此處執行賦值語句(將buy方法返回的結果賦值給變量myPhone)
*/
String myPhone = buy(1000.0);
System.out.println("使用\"" + myPhone + "\"撥打電話...");
/*
* return語句可有可無
* 需要注意的是,執行return語句後方法就結束了
* 所以return語句後面還有語句的話就不會被執行
*/
return;
//以下位置(此處開始至方法的右大括號之間)再寫代碼就會提示錯誤
}
public static void main(String[] args) {
//創建一個人類的對象
Person person = new Person();
/*
* 程序由main方法進入執行
* 執行到此處調用call方法,程序會跳到call方法中執行
* 當call方法中遇到return或所有代碼都執行完成(未寫return語句時)後
* 再回到當前位置,執行後面的輸出語句
*/
person.call();
//call方法執行完成後,繼續執行此句
System.out.println("main方法的最後一句代碼");
}
}
運行結果:
使用"華爲手機"撥打電話...
main方法的最後一句代碼
方法調用語句
語法格式:對象名.方法名();或 類名.靜態方法名();(下面講到)例如上例中用到的 person.call();
方法傳參
值傳遞(基本數據類型)
將實參變量中保存的值複製一份,賦值給形參變量;賦值之後實參變量和形參變量沒有任何關係,修改任何一個變量,另一個變量都不會發生變量引用傳遞(引用類型,String除外)
將實參變量中存儲的對象的內存地址複製一份賦值給形參變量,此時實參變量和形參變量中保存的是同一個對象的內存地址;使用任何一個引用對對象的屬性進行修改,再次使用任何一個引用訪問對象被修改的屬性時都會發生變化。/**
* 聲明汽車類Car
* @author 學霸聯盟 - 趙燦
*/
class Car{
//聲明一個String類型的變量name
String carName;
//聲明一個變量color代表汽車的顏色,並賦值
String color = "無色";
}
/**
* 聲明汽車工廠類CarFactory
* @author 學霸聯盟 - 趙燦
*/
class CarFactory{
/**
* 聲明一個結賬的方法
* 用於測試參數的值傳遞
* 參數money用於接收用戶付款
*/
void settlement(double money){
System.out.println("用戶付款:" + money);
//修理費150
double repairs = 150;
//對變量money進行修改,得到收取修理費剩餘的錢
money = money - repairs;
System.out.println("應找零:" + money);
}
/**
* 聲明一個修改汽車顏色的方法
* 用於測試參數的引用傳遞
* 參數car用於接收被修改顏色的汽車
*/
void setColor(Car car) {
// 將接收到的汽車的顏色設置成黑色
car.color = "黑色";
}
}
/**
* 演示值傳遞和引用傳遞
*
* @author 學霸聯盟 - 趙燦
*/
public class ParameterTransferDemo {
// 聲明一個main方法,作爲程序的入口
public static void main(String[] args) {
System.out.println("------------ 引用傳遞 ------------");
//使用關鍵字new創建汽車對象,並將對象在內存中的地址賦值給變量c
Car c = new Car();
c.carName = "小c";
System.out.println("剛剛創建出來的汽車\"" + c.carName + "\"的顏色是:" + c.color);
//創建汽車工廠對象cf
CarFactory cf = new CarFactory();
//引用傳遞:將變量c中存儲的地址,傳遞給setColor方法的參數car
cf.setColor(c);
//輸出結果汽車的名字還是小c,這表明汽車還是原來的汽車,但是顏色已經變了
System.out.println("通過汽車工廠修改後\"" + c.carName + "\"的顏色是:" + c.color);
System.out.println("------------- 值傳遞 -------------");
double myMoney = 200;
System.out.println("付款前我的錢是:" + myMoney);
//值傳遞:調用結算的方法settlement,將myMoney的值傳給參數money
cf.settlement(myMoney);
System.out.println("付款後我的錢是:" + myMoney);
/*
* 前面說過,方法的傳參相當於用實參給形參賦值
* 下面這段代碼中,變量c1代表上面的變量c
* 變量c2代表setColor方法中的參數car
*/
System.out.println("------------ 引用傳遞 ------------");
//創建一個汽車對象,並將汽車對象在內存中的地址賦值給變量c1
Car c1 = new Car();
//設置名稱
c1.carName = "小c1";
//由於引用類型變量中存儲的是對象在內存中的地址
//所以引用類型的變量也稱爲引用
Car c2 = c1;
System.out.println("修改前汽車c1的名稱:" + c1.carName + " 顏色:" + c1.color);
System.out.println("修改前汽車c2的名稱:" + c2.carName + " 顏色:" + c2.color);
//對c2的修改會影響c1,c1跟着變化
c2.color = "黑色";
System.out.println("修改後汽車c1的名稱:" + c1.carName + " 顏色:" + c1.color);
System.out.println("修改後汽車c2的名稱:" + c2.carName + " 顏色:" + c2.color);
System.out.println("------------- 值傳遞 -------------");
double m1 = 200;
double m2 = m1;
System.out.println("修改前m1的值:" + m1);
System.out.println("修改前m2的值:" + m2);
//對m2的修改不會影響m1
m2 = m2 - 150;
System.out.println("修改後m1的值:" + m1);
System.out.println("修改後m2的值:" + m2);
}
}
運行結果:
------------ 引用傳遞 ------------
剛剛創建出來的汽車"小c"的顏色是:無色
通過汽車工廠修改後"小c"的顏色是:黑色
------------- 值傳遞 -------------
付款前我的錢是:200.0
用戶付款:200.0
應找零:50.0
付款後我的錢是:200.0
------------ 引用傳遞 ------------
修改前汽車c1的名稱:小c1 顏色:無色
修改前汽車c2的名稱:小c1 顏色:無色
修改後汽車c1的名稱:小c1 顏色:黑色
修改後汽車c2的名稱:小c1 顏色:黑色
------------- 值傳遞 -------------
修改前m1的值:200.0
修改前m2的值:200.0
修改後m1的值:200.0
修改後m2的值:50.0
構造方法(構造器)
使用new關鍵字創建對象時會被調用,一般用於初始化類中的一些變量。語法格式:[訪問修飾符] 類名([參數列表]){ //方法體 }
實例:
/**
* 演示構造方法
* @author 學霸聯盟 - 趙燦
*/
public class CustomerDemo {
String name;
/**
* 構造方法的方法名必須嚴格和類名一致
* 不能有返回值類型
* 如果不寫,系統自動提供一個沒有參數的構造方法
* 如果寫了,無論寫的構造方法帶不帶參數,系統都不再系統無參構造
*/
CustomerDemo(String str) {
//初始化:第一次賦值
name = str;
}
public static void main(String[] args) {
/*
* 通過new創建對象時,會先將變量name加載到內存中,然後執行構造方法
* 由於在CustomerDemo類中聲明瞭帶一個String類型參數的構造方法
* 所以系統將不會再爲CustomerDemo類提供無參的構造方法了
* 所以使用new創建對象時必須傳入參數
*/
CustomerDemo cd = new CustomerDemo("abc");
//輸出結果:abc
System.out.println(cd.name);
}
}
運行結果:abc
注意: 1、沒有返回值類型,方法名和類名完全一致(包括大小寫也必須一致)2、使用new創建對象時,先將在堆中創建一塊內存空間,將屬性加載到這塊內存空間中,然後執行構造方法
3、如果不寫構造方法,系統會自動提供一個無參的構造方法
4、如果寫了構造方法,系統將不再提供無參構造
5、如果構造方法前寫了返回值類型,該方法便不是構造方法了,只不過是一個名字和類名相同的普通方法
構造方法和普通方法的區別
1、 返回值類型:構造方法沒有返回值類型,普通方法必須有(如果不需要返回值,寫void)2、 方法名:構造方法的方法名和類名完全一致(包括大小寫也必須一致),普通方法的方法名自定義
3、 構造方法可以使用關鍵字this、super調用,new操作時也會調用,普通方法是用對象名.方法名();的方法調用
4、 一個類中,如果不寫構造方法,系統會自動提供一個無參的構造方法;如果寫了構造方法,系統將不再提供無參構造;
5、 如果構造方法前寫了返回值類型,該方法便不是構造方法了,只不過是一個名字和類名相同的普通方法
方法的重載:@Overload
方法重載是描述同一個類中,相同方法名之間的關係。無論是普通方法還是構造方法,都可以被重載。
例如:一個類中包含多個構造方法和多個同名的方法
/**
* 演示方法的重載(overload)
* @author 學霸聯盟 - 趙燦
*/
public class OverloadDemo {
String str;
/*
* 創建了兩個構造方法,這兩個構造方法就構成了重載
*/
OverloadDemo(){}
OverloadDemo(String s){
str = s;
}
/*
* 創建了兩個普通方法
* 兩個方法的方法名相同,參數列表不同
* 他們也構造了方法重載
* 但是如果兩個方法名相同,參數列表也相同,就會導致方法同名的錯誤
*/
void m1(){}
void m1(String s){
str = s;
}
public static void main(String[] args) {
//這種方式創建對象時會調用類的無參構造
OverloadDemo od1 = new OverloadDemo();
//這種方式創建對象,會調用類中帶一個String類型參數的構造方法
OverloadDemo od2 = new OverloadDemo("abc");
//輸出結果:null
System.out.println(od1.str);
//輸出結果:abc
System.out.println(od2.str);
}
}
運行結果:
null
abc
方法重載需要滿足的條件:
1、在同一類中2、方法名相同
3、參數列表不同