wordpress添加友情練級(jí)濟(jì)南seo網(wǎng)絡(luò)優(yōu)化公司
類和對(duì)象的區(qū)別和聯(lián)系
類:類是封裝對(duì)象的屬性和行為的載體,在Java語言中對(duì)象的屬性以成員變量的形式存在,而對(duì)象的方法以成員方法的形式存在。
對(duì)象:Java是面向?qū)ο蟮某绦蛟O(shè)計(jì)語言,對(duì)象是由類抽象出來的,所有的問題都是通過對(duì)象來處理,對(duì)象可以操作類的基本屬性和方法解決相應(yīng)的問題。
聯(lián)系:類是對(duì)象的抽象,而對(duì)象時(shí)類的具體實(shí)例。
類與對(duì)象的關(guān)系示意圖
類和對(duì)象的區(qū)別和聯(lián)系
- 1) 類是抽象的,概念的,代表一類事物,比如人類,貓類.., 即它是數(shù)據(jù)類型.
- 2) 對(duì)象是具體的,實(shí)際的,代表一個(gè)具體事物, 即 是實(shí)例.
- 3) 類是對(duì)象的模板,對(duì)象是類的一個(gè)個(gè)體,對(duì)應(yīng)一個(gè)實(shí)例
對(duì)象在內(nèi)存中存在形式(重要的)必須搞清楚。
屬性/成員變量/字段
- 從概念或叫法上看: 成員變量 = 屬性 =field(字段) (即 成員變量是用來表示屬性的,授課中,統(tǒng)一叫 屬性
- 屬性是類的一個(gè)組成部分,可以時(shí)基本數(shù)據(jù)類型,也可以是引用類型(對(duì)象,數(shù)組)
細(xì)節(jié)說明
- 1.屬性的定義語法與變量相同,但是增加了訪問修飾符
(控制屬性的訪問范圍,共4種 public protected 默認(rèn) private)
格式:訪問修飾符 屬性類型 屬性名 - 2.屬性可以定義任意類型,包含基本類型或引用類型
- 3.屬性如果不賦值,有默認(rèn)值,規(guī)則和數(shù)組一致
具體說:int 0,short 0,byte 0,long 0,
float 0.0,double 0.0,char \u0000, boolean false,String null
public class PropertiesDetail{public static void main(String[] args) {//創(chuàng)建Person對(duì)象//p1 是對(duì)象名(對(duì)象引用)//new Person() 創(chuàng)建的對(duì)象空間(數(shù)據(jù)) 才是真正的對(duì)象Person p1 = new Person();//對(duì)象的屬性默認(rèn)值,遵守?cái)?shù)組規(guī)則:// int 0,short 0, byte 0, long 0, float 0.0,double 0.0,// char \u0000,boolean false,String null// System.out.println("當(dāng)前這個(gè)人的信息為");System.out.print("age=" + p1.age + "name=" + p1.name + "sal=" + p1.sal + "isPass" + p1.isPass);}
}
class Person{int age;String name;double sal;boolean isPass;
}
如何創(chuàng)建對(duì)象
- 1) 先聲明再創(chuàng)建
Cat cat ; //聲明對(duì)象 cat
?
cat = new Cat(); //創(chuàng)建
- 2) 直接創(chuàng)建
Cat cat = new Cat();
如何訪問屬性
基本語法 對(duì)象名.屬性名; 案例演示賦值和輸出 cat.name ; cat.age; cat.color;
類和對(duì)象的內(nèi)存分配機(jī)制(重要)
我們定義一個(gè)人類(Person)(包括 名字,年齡)。 (Object03.java)
類和對(duì)象的內(nèi)存分配機(jī)制
Java內(nèi)存的結(jié)構(gòu)分析
- 1)棧:一般存放基本數(shù)據(jù)類型(局部變量)
- 2)堆:存放對(duì)象(Catcat,數(shù)組等)
- 3)方法區(qū):常量池(常量,比如字符串),類加載信息
成員方法
基本介紹
在某些情況下,我們要需要定義成員方法(簡稱方法)。比如人類:除了有一些屬性外(年齡,姓名..),我們?nèi)祟愡€有一 些行為比如:可以說話、跑步..,通過學(xué)習(xí),還可以做算術(shù)題。這時(shí)就要用成員方法才能完成?,F(xiàn)在要求對(duì)Person類完善。
成員方法快速入門
- 1)添加 speak 成員方法,輸出 “我是一個(gè)好人”
- 2)添加 cal01 成員方法,可以計(jì)算從 1+..+1000 的結(jié)果
- 3)添加 cal02 成員方法,該方法可以接收一個(gè)數(shù) n,計(jì)算從 1+..+n 的結(jié)果
- 4)添加 getSum 成員方法,可以計(jì)算兩個(gè)數(shù)的和
public class Method01 {
?//編寫一個(gè)main方法public static void main(String[] args) {//方法使用//1. 方法寫好后,如果不去調(diào)用(使用),不會(huì)輸出//2. 先創(chuàng)建對(duì)象 ,然后調(diào)用方法即可Person p1 = new Person();p1.speak(); //調(diào)用方法p1.cal01(); //調(diào)用cal01方法p1.cal02(5); //調(diào)用cal02方法,同時(shí)給n = 5p1.cal02(10); //調(diào)用cal02方法,同時(shí)給n = 10//調(diào)用getSum方法,同時(shí)num1=10, num2=20//把 方法 getSum 返回的值,賦給 變量 returnResint returnRes = p1.getSum(10, 20); System.out.println("getSum方法返回的值=" + returnRes);}
}
?
class Person {String name;int age;//方法(成員方法)//添加speak 成員方法,輸出 “我是一個(gè)好人”//老韓解讀//1. public 表示方法是公開//2. void : 表示方法沒有返回值//3. speak() : speak是方法名, () 形參列表//4. {} 方法體,可以寫我們要執(zhí)行的代碼//5. System.out.println("我是一個(gè)好人"); 表示我們的方法就是輸出一句話public void speak() {System.out.println("我是一個(gè)好人");}
?//添加cal01 成員方法,可以計(jì)算從 1+..+1000的結(jié)果public void cal01() {//循環(huán)完成int res = 0;for(int i = 1; i <= 1000; i++) {res += i;}System.out.println("cal01方法 計(jì)算結(jié)果=" + res);}//添加cal02 成員方法,該方法可以接收一個(gè)數(shù)n,計(jì)算從 1+..+n 的結(jié)果//老韓解讀//1. (int n) 形參列表, 表示當(dāng)前有一個(gè)形參 n, 可以接收用戶輸入public void cal02(int n) {//循環(huán)完成int res = 0;for(int i = 1; i <= n; i++) {res += i;}System.out.println("cal02方法 計(jì)算結(jié)果=" + res);}
?//添加getSum成員方法,可以計(jì)算兩個(gè)數(shù)的和//老韓解讀//1. public 表示方法是公開的//2. int :表示方法執(zhí)行后,返回一個(gè) int 值//3. getSum 方法名//4. (int num1, int num2) 形參列表,2個(gè)形參,可以接收用戶傳入的兩個(gè)數(shù)//5. return res; 表示把 res 的值, 返回public int getSum(int num1, int num2) {int res = num1 + num2;return res;}
}
方法的調(diào)用機(jī)制原理:(重要!)
提示:畫出程序執(zhí)行過程[getSum]+說明
成員方法的好處
1)提高代碼的復(fù)用性
2)可以將實(shí)現(xiàn)的細(xì)節(jié)封裝起來,然后供其他用戶來調(diào)用即可
成員方法的定義
訪問修飾符 返回?cái)?shù)據(jù)類型 方法名(形參列表..) {//方法體語句;return 返回值;
}
- 1)形參列表:表示成員方法輸入 cal(int n) , getSum(int num1, int num2)
- 2)返回?cái)?shù)據(jù)類型:表示成員方法輸出, void 表示沒有返回值
- 3)方法主體:表示為了實(shí)現(xiàn)某一功能代碼塊
- 4)return 語句不是必須的。
注意事項(xiàng)和使用細(xì)節(jié)
public class MethodDetail {
?public static void main(String[] args) {
?AA a = new AA();int[] res = a.getSumAndSub(1, 4);System.out.println("和=" + res[0]);System.out.println("差=" + res[1]);//細(xì)節(jié): 調(diào)用帶參數(shù)的方法時(shí),一定對(duì)應(yīng)著參數(shù)列表傳入相同類型或兼容類型 的參數(shù)byte b1 = 1;byte b2 = 2;a.getSumAndSub(b1, b2);//byte -> int //a.getSumAndSub(1.1, 1.8);//double ->int(×)//細(xì)節(jié): 實(shí)參和形參的類型要一致或兼容、個(gè)數(shù)、順序必須一致//a.getSumAndSub(100);//× 個(gè)數(shù)不一致a.f3("tom", 10); //ok//a.f3(100, "jack"); // 實(shí)際參數(shù)和形式參數(shù)順序不對(duì)}
}
?
class AA {
?//細(xì)節(jié): 方法不能嵌套定義public void f4() {//錯(cuò)誤// public void f5() {
?// }}
?public void f3(String str, int n) {
?}
?//1. 一個(gè)方法最多有一個(gè)返回值 [思考,如何返回多個(gè)結(jié)果 返回?cái)?shù)組 ]public int[] getSumAndSub(int n1, int n2) {
?int[] resArr = new int[2]; //resArr[0] = n1 + n2;resArr[1] = n1 - n2;return resArr;}//2. 返回類型可以為任意類型,包含基本類型或引用類型(數(shù)組,對(duì)象)// 具體看 getSumAndSub //3. 如果方法要求有返回?cái)?shù)據(jù)類型,則方法體中最后的執(zhí)行語句必須為 return 值; // 而且要求返回值類型必須和return的值類型一致或兼容public double f1() {
?double d1 = 1.1 * 3;int n = 100;return n; // int ->double //return d1; //ok? double -> int }
?//如果方法是void,則方法體中可以沒有return語句,或者 只寫 return ; //老韓提示:在實(shí)際工作中,我們的方法都是為了完成某個(gè)功能,所以方法名要有一定含義//,最好是見名知意public void f2() {
?System.out.println("hello1");System.out.println("hello1");System.out.println("hello1");int n = 10;//return ;}
?
}
訪問修飾符 (作用是控制 方法使用的范圍)
- 如果不寫默認(rèn)訪問,[有四種: public, protected, 默認(rèn), private], 具體在后面說
返回?cái)?shù)據(jù)類型
- 1)一個(gè)方法最多有一個(gè)返回值 [思考,如何返回多個(gè)結(jié)果 -> 返回?cái)?shù)組 ]
- 2)返回類型可以為任意類型,包含基本類型或引用類型(數(shù)組,對(duì)象)
- 3)如果方法要求有返回?cái)?shù)據(jù)類型,則方法體中最后的執(zhí)行語句必須為 return 值; 而且要求返回值類型必須和 return 的值類型一致或兼容
- 4)如果方法是 void,則方法體中可以沒有 return 語句,或者 只寫 return ;
方法名
- 遵循駝峰命名法,最好見名知義,表達(dá)出該功能的意思即可, 比如 得到兩個(gè)數(shù)的和 getSum, 開發(fā)中按照規(guī)范
形參列表
- 一個(gè)方法可以有0個(gè)參數(shù),也可以有多個(gè)參數(shù),中間用逗號(hào)隔開,比如 getsum(int n1,int n2)
- 參數(shù)類型可以為任意類型,包含基本類型或引用類型,比如printArr(int[] [] map)
- 調(diào)用帶參數(shù)的方法時(shí),一定對(duì)應(yīng)著參數(shù)列表傳入相同類型或兼容類型 的參數(shù)!(先精準(zhǔn)匹配,再類型轉(zhuǎn)換)【getsum】
- 方法定義時(shí)的參數(shù)稱為形式參數(shù),簡稱形參;方法調(diào)用時(shí)的傳入?yún)?shù)稱為實(shí)際參數(shù),簡稱實(shí)參,實(shí)參和形參的類型要一致或兼容、個(gè)數(shù)、順序必須一致![演示]
方法體
- 里面寫完成功能的具體的語句,可以為輸入、輸出、變量、運(yùn)算、分支、循環(huán)、方法調(diào)用,但里面不能再定義方法!即:方法不能嵌套定義。[演示]
方法調(diào)用細(xì)節(jié)說明(!!!)
- 同一個(gè)類中的方法調(diào)用:直接調(diào)用即可。比如 print(參數(shù));
- 跨類中的方法A類調(diào)用B類方法:需要通過對(duì)象名調(diào)用。比如 對(duì)象名.方法名(參數(shù));案例演示:B類 sayHello 調(diào)用 print()
- 特別說明一下:跨類的方法調(diào)用和方法的訪問修飾符相關(guān),后面到訪問修飾符時(shí),還要再細(xì)說。
public class MethodDetail02 {
?//編寫一個(gè)main方法public static void main(String[] args) {
?A a = new A();//a.sayOk();
?a.m1(); }
}
?
class A {//同一個(gè)類中的方法調(diào)用:直接調(diào)用即可//public void print(int n) {System.out.println("print()方法被調(diào)用 n=" + n);}
?public void sayOk() { //sayOk調(diào)用 print(直接調(diào)用即可)print(10);System.out.println("繼續(xù)執(zhí)行sayOK()~~~");}
?//跨類中的方法A類調(diào)用B類方法:需要通過對(duì)象名調(diào)用public void m1() {//創(chuàng)建B對(duì)象, 然后在調(diào)用方法即可System.out.println("m1() 方法被調(diào)用");B b = new B();b.hi();
?System.out.println("m1() 繼續(xù)執(zhí)行:)");}
}
?
class B {
?public void hi() {System.out.println("B類中的 hi()被執(zhí)行");}
}
成員方法傳參機(jī)制(非常非常重要)
基本數(shù)據(jù)類型的傳參機(jī)制
public class MethodParameter01 { //編寫一個(gè)main方法public static void main(String[] args) {int a = 10;int b = 20;//創(chuàng)建AA對(duì)象 名字 objAA obj = new AA();obj.swap(a, b); //調(diào)用swap
?System.out.println("main方法 a=" + a + " b=" + b);//a=10 b=20}
}
?
class AA {public void swap(int a,int b){System.out.println("\na和b交換前的值\na=" + a + "\tb=" + b);//a=10 b=20//完成了 a 和 b的交換int tmp = a;a = b;b = tmp;System.out.println("\na和b交換后的值\na=" + a + "\tb=" + b);//a=20 b=10}
}
引用數(shù)據(jù)類型的傳參機(jī)制
1)看一個(gè)案例
B 類中編寫一個(gè)方法 test100,可以接收一個(gè)數(shù)組,在方法中修改該數(shù)組,看看原來的數(shù)組是否變化?會(huì)變化
B 類中編寫一個(gè)方法 test200,可以接收一個(gè) Person(age,sal)對(duì)象,在方法中修改該對(duì)象屬性,看看原來的對(duì)象是否變化?會(huì)變化
public class MethodParameter02 { //編寫一個(gè)main方法public static void main(String[] args) {//測試B b = new B();// int[] arr = {1, 2, 3};// b.test100(arr);//調(diào)用方法// System.out.println(" main的 arr數(shù)組 ");// //遍歷數(shù)組// for(int i = 0; i < arr.length; i++) {// System.out.print(arr[i] + "\t");// }// System.out.println();//200,2,3
?//測試Person p = new Person();p.name = "jack";p.age = 10;b.test200(p);//測試題, 如果 test200 執(zhí)行的是 p = null ,下面的結(jié)果是 10//測試題, 如果 test200 執(zhí)行的是 p = new Person();..., 下面輸出的是10System.out.println("main 的p.age=" + p.age);//10000 }
}
class Person {String name;int age;
}
class B {public void test200(Person p) {//p.age = 10000; //修改對(duì)象屬性//思考p = new Person();p.name = "tom";p.age = 99;//思考//p = null; }
?//B類中編寫一個(gè)方法test100,//可以接收一個(gè)數(shù)組,在方法中修改該數(shù)組,看看原來的數(shù)組是否變化public void test100(int[] arr) {arr[0] = 200;//修改元素//遍歷數(shù)組System.out.println(" test100的 arr數(shù)組 ");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + "\t");}System.out.println();}
}
結(jié)論及示意圖 引用類型傳遞的是地址(傳遞也是值,但是值是地址),可以通過形參影響實(shí)參!
3) 在看一個(gè)案例,下面的方法會(huì)對(duì)原來的對(duì)象有影響嗎?
p=null 和 p=new Person(); 對(duì)應(yīng)示意圖
成員方法返回類型是引用類型應(yīng)用實(shí)例
1) 編寫類MyTools類,編寫一個(gè)方法可以打印二維數(shù)組的數(shù)據(jù)。
2) 編寫一個(gè)方法copyPerson,可以復(fù)制一個(gè)Person對(duì)象,返回復(fù)制的對(duì)象??寺?duì)象, 注意要求得到新對(duì)象和原來的 對(duì)象是兩個(gè)獨(dú)立的對(duì)象,只是他們的屬性相同
public class MethodExercise02 {
?//編寫一個(gè)main方法public static void main(String[] args) {Person p = new Person();p.name = "milan";p.age = 100;//創(chuàng)建toolsMyTools tools = new MyTools();Person p2 = tools.copyPerson(p);
?//到此 p 和 p2是Person對(duì)象,但是是兩個(gè)獨(dú)立的對(duì)象,屬性相同System.out.println("p的屬性 age=" + p.age + " 名字=" + p.name);System.out.println("p2的屬性 age=" + p2.age + " 名字=" + p2.name);//這里老師提示: 可以同 對(duì)象比較看看是否為同一個(gè)對(duì)象System.out.println(p == p2);//false?}
}
?
class Person {String name;int age;
}
?
class MyTools {//編寫一個(gè)方法copyPerson,可以復(fù)制一個(gè)Person對(duì)象,返回復(fù)制的對(duì)象??寺?duì)象, //注意要求得到新對(duì)象和原來的對(duì)象是兩個(gè)獨(dú)立的對(duì)象,只是他們的屬性相同////編寫方法的思路//1. 方法的返回類型 Person//2. 方法的名字 copyPerson//3. 方法的形參 (Person p)//4. 方法體, 創(chuàng)建一個(gè)新對(duì)象,并復(fù)制屬性,返回即可public Person copyPerson(Person p) {//創(chuàng)建一個(gè)新的對(duì)象Person p2 = new Person();p2.name = p.name; //把原來對(duì)象的名字賦給p2.namep2.age = p.age; //把原來對(duì)象的年齡賦給p2.agereturn p2;}
}
方法遞歸調(diào)用(非常非常重要,比較難)
基本介紹 簡單的說: 遞歸就是方法自己調(diào)用自己,每次調(diào)用時(shí)傳入不同的變量.遞歸有助于編程者解決復(fù)雜問題,同時(shí)可以讓代碼變 得簡潔
遞歸能解決什么問題?
- 1. 各種數(shù)學(xué)問題如: 8皇后問題,漢諾塔,階乘問題,迷宮問題,球和籃子的問題(google編程大賽)[簡單演示]
- 2.各種算法中也會(huì)使用到遞歸,比如快排,歸并排序,二分查找,分治算法等.
- 3.將用棧解決的問題-->遞歸代碼比較簡潔
遞歸舉例
列舉兩個(gè)小案例,來幫助大家理解遞歸調(diào)用機(jī)制
1)打印問題? ?
2)階乘問題
public class Recursion01 {
?//編寫一個(gè)main方法public static void main(String[] args) {
?T t1 = new T();t1.test(4);//輸出什么? n=2 n=3 n=4int res = t1.factorial(5); System.out.println("5的階乘 res =" + res);}
}
?
class T {//分析public void test(int n) {if (n > 2) {test(n - 1);} System.out.println("n=" + n);}
?//factorial 階乘//入口和出口public int factorial(int n) {if (n == 1) {return 1;} else {return factorial(n - 1) * n;}}
?
}
遞歸重要規(guī)則
- 執(zhí)行一個(gè)方法時(shí),就創(chuàng)建一個(gè)新的受保護(hù)的獨(dú)立空間(棧空間)
- 方法的局部變量是獨(dú)立的,不會(huì)相互影響,比如n變量
- 如果方法中使用的是引用類型變量(比如數(shù)組,對(duì)象),就會(huì)共享該引用類型的數(shù)據(jù)
- 遞歸必須向退出遞歸的條件逼近,否則就是無限遞歸,出現(xiàn)StackOverflowError,死龜了;)
- 當(dāng)一個(gè)方法執(zhí)行完畢,或者遇到return,就會(huì)返回,遵守誰調(diào)用,就將結(jié)果返回給誰,同時(shí)當(dāng)方法執(zhí)行完畢或者返回時(shí),該方法也就執(zhí)行完畢。
方法重載(OverLoad)
基本介紹
java 中允許同一個(gè)類中,多個(gè)同名方法的存在,但要求 形參列表不一致!
比如:System.out.println(); out 是 PrintStream 類型
重載的好處
1)減輕了起名的麻煩
2)減輕了記名的麻煩
快速入門案例
案例:類:MyCalculator 方法:calculate
1)calculate(int n1, int n2) //兩個(gè)整數(shù)的和
2)calculate(int n1, double n2) //一個(gè)整數(shù),一個(gè) double 的和
3)calculate(double n2, int n1)//一個(gè) double ,一個(gè) Int 和
4)calculate(int n1, int n2,int n3)//三個(gè) int 的和
public class OverLoad01 {
?//編寫一個(gè)main方法public static void main(String[] args) {// 比如:System.out.println(); out 是 PrintStream 類型// System.out.println(100);// System.out.println("hello,world");// System.out.println('h');// System.out.println(1.1);// System.out.println(true);MyCalculator mc = new MyCalculator();System.out.println(mc.calculate(1, 2));System.out.println(mc.calculate(1.1, 2));System.out.println(mc.calculate(1, 2.1));}
}
?
class MyCalculator {
?//下面的四個(gè) calculate方法構(gòu)成了重載//兩個(gè)整數(shù)的和public int calculate(int n1, int n2) {System.out.println("calculate(int n1, int n2) 被調(diào)用");return n1 + n2;}
?//沒有構(gòu)成方法重載, 仍然是錯(cuò)誤的,因?yàn)槭欠椒ǖ闹貜?fù)定義// public void calculate(int n1, int n2) {// System.out.println("calculate(int n1, int n2) 被調(diào)用");// int res = n1 + n2;// }
?//看看下面是否構(gòu)成重載, 沒有構(gòu)成,而是方法的重復(fù)定義,就錯(cuò)了// public int calculate(int a1, int a2) {// System.out.println("calculate(int n1, int n2) 被調(diào)用");// return a1 + a2;// }
?//一個(gè)整數(shù),一個(gè)double的和public double calculate(int n1, double n2) {return n1 + n2;}//一個(gè)double ,一個(gè)Int和 public double calculate(double n1, int n2) {System.out.println("calculate(double n1, int n2) 被調(diào)用..");return n1 + n2;}//三個(gè)int的和public int calculate(int n1, int n2,int n3) {return n1 + n2 + n2;}
?
}
注意事項(xiàng)和使用細(xì)節(jié)
1)方法名:必須相同
2)形參列表:必須不同 (形參類型或個(gè)數(shù)或順序,至少有一樣不同,參數(shù)名無要求)
3)返回類型:無要求
可變參數(shù)
java 允許將同一個(gè)類中多個(gè)同名同功能但參數(shù)個(gè)數(shù)不同的方法,封裝成一個(gè)方法。就可以通過可變參數(shù)實(shí)現(xiàn)
基本語法
訪問修飾符 返回類型 方法名(數(shù)據(jù)類型... 形參名) {
}
快速入門案例
public class VarParameter01 {
?//編寫一個(gè)main方法public static void main(String[] args) {
?HspMethod m = new HspMethod();System.out.println(m.sum(1, 5, 100)); //106System.out.println(m.sum(1,19)); //20}
}
?
class HspMethod {//可以計(jì)算 2個(gè)數(shù)的和,3個(gè)數(shù)的和 , 4. 5, 。。//可以使用方法重載// public int sum(int n1, int n2) {//2個(gè)數(shù)的和// return n1 + n2;// }// public int sum(int n1, int n2, int n3) {//3個(gè)數(shù)的和// return n1 + n2 + n3;// }// public int sum(int n1, int n2, int n3, int n4) {//4個(gè)數(shù)的和// return n1 + n2 + n3 + n4;// }//.....//上面的三個(gè)方法名稱相同,功能相同, 參數(shù)個(gè)數(shù)不同-> 使用可變參數(shù)優(yōu)化//老韓解讀//1. int... 表示接受的是可變參數(shù),類型是int ,即可以接收多個(gè)int(0-多) //2. 使用可變參數(shù)時(shí),可以當(dāng)做數(shù)組來使用 即 nums 可以當(dāng)做數(shù)組//3. 遍歷 nums 求和即可public int sum(int... nums) {//System.out.println("接收的參數(shù)個(gè)數(shù)=" + nums.length);int res = 0;for(int i = 0; i < nums.length; i++) {res += nums[i];}return res;}
}
注意事項(xiàng)和使用細(xì)節(jié)
1)可變參數(shù)的實(shí)參可以為0個(gè)或任意多個(gè)。
2)可變參數(shù)的實(shí)參可以為數(shù)組。
3)可變參數(shù)的本質(zhì)就是數(shù)組.
4)可變參數(shù)可以和普通類型的參數(shù)一起放在形參列表,但必須保證可變參數(shù)在最后
5)個(gè)形參列表中只能出現(xiàn)一個(gè)可變參數(shù)
代碼
public class VarParameterDetail { //編寫一個(gè)main方法public static void main(String[] args) {//細(xì)節(jié): 可變參數(shù)的實(shí)參可以為數(shù)組int[] arr = {1, 2, 3};T t1 = new T();t1.f1(arr);}
}
?
class T {
?public void f1(int... nums) {System.out.println("長度=" + nums.length);}
?//細(xì)節(jié): 可變參數(shù)可以和普通類型的參數(shù)一起放在形參列表,但必須保證可變參數(shù)在最后public void f2(String str, double... nums) {
?}//細(xì)節(jié): 一個(gè)形參列表中只能出現(xiàn)一個(gè)可變參數(shù)//下面的寫法是錯(cuò)的.// public void f3(int... nums1, double... nums2) {// }
}
課堂練習(xí)
有三個(gè)方法,分別實(shí)現(xiàn)返回姓名和兩門課成績(總分),返回姓名和三門課成績(總分),返回姓名和五門課成績(總分)。封裝成一個(gè)可變參數(shù)的方法
類名HspMethod方法名showScore
public class VarParameterExercise {
?//編寫一個(gè)main方法public static void main(String[] args) {HspMethod hm = new HspMethod();System.out.println(hm.showScore("milan" , 90.1, 80.0 ));System.out.println(hm.showScore("terry" , 90.1, 80.0,10,30.5,70 ));}
}
?
class HspMethod {
?/*有三個(gè)方法,分別實(shí)現(xiàn)返回姓名和兩門課成績(總分),返回姓名和三門課成績(總分),返回姓名和五門課成績(總分)。封裝成一個(gè)可變參數(shù)的方法*///分析1. 方法名 showScore 2. 形參(String ,double... ) 3. 返回String//聽課小伙伴,老師要求必須自己動(dòng)手寫public String showScore(String name ,double... scores ) {
?double totalScore = 0;for(int i = 0; i < scores.length; i++) {totalScore += scores[i];}return name + " 有 " +scores.length + "門課的成績總分為=" + totalScore;}}
作用域
基本使用
面向?qū)ο笾?#xff0c;變量作用域是非常重要知識(shí)點(diǎn),相對(duì)來說不是特別好理解,請(qǐng)大家認(rèn)真思考,要求深刻掌握變量作用域。
- 在java編程中,主要的變量就是屬性(成員變量)和局部變量。
- 我們說的局部變量一般是指在成員方法中定義的變量?!九e例Cat類:cry】
- java中作用域的分類
全局變量:也就是屬性,作用域?yàn)檎麄€(gè)類體 Cat類:cry eat 等方法使用屬性【舉例】
局部變量:也就是除了屬性之外的其他變量,作用域?yàn)槎x它的代碼塊中! - 全局變量(屬性)可以不賦值,直接使用,因?yàn)橛心J(rèn)值,局部變量必須賦值后才能使用,因?yàn)闆]有默認(rèn)值。[舉例]
public class VarScope {
?//編寫一個(gè)main方法public static void main(String[] args) {}
}
class Cat {//全局變量:也就是屬性,作用域?yàn)檎麄€(gè)類體 Cat類:cry eat 等方法使用屬性//屬性在定義時(shí),可以直接賦值int age = 10; //指定的值是 10
?//全局變量(屬性)可以不賦值,直接使用,因?yàn)橛心J(rèn)值,double weight; //默認(rèn)值是0.0
?public void hi() {//局部變量必須賦值后,才能使用,因?yàn)闆]有默認(rèn)值int num = 1;String address = "北京的貓";System.out.println("num=" + num);System.out.println("address=" + address);System.out.println("weight=" + weight);//屬性}public void cry() {//1. 局部變量一般是指在成員方法中定義的變量//2. n 和 name 就是局部變量//3. n 和 name的作用域在 cry方法中int n = 10;String name = "jack";System.out.println("在cry中使用屬性 age=" + age);}
?public void eat() {
?System.out.println("在eat中使用屬性 age=" + age);?//System.out.println("在eat中使用 cry的變量 name=" + name);//錯(cuò)誤}
}
注意事項(xiàng)和細(xì)節(jié)使用
- 屬性和局部變量可以重名,訪問時(shí)遵循就近原則。
- 在同一個(gè)作用域中,比如在同一個(gè)成員方法中,兩個(gè)局部變量,不能重名。[舉例]
- 屬性生命周期較長,伴隨著對(duì)象的創(chuàng)建而創(chuàng)建,伴隨著對(duì)象的銷毀而銷毀。
局部變量,生命周期較短,伴隨著它的代碼塊的執(zhí)行而創(chuàng)建,伴隨著代碼塊的結(jié)束而銷毀即在一次方法調(diào)用過程中。 - 作用域范圍不同
全局變量/屬性:可以被本類使用,或其他類使用(通過對(duì)象調(diào)用)
局部變量:只能在本類中對(duì)應(yīng)的方法中使用 - ?修飾符不同
全局變量/屬性可以加修飾符
局部變量不可以加修飾符
public class VarScopeDetail {
?//編寫一個(gè)main方法public static void main(String[] args) {Person p1 = new Person();/*屬性生命周期較長,伴隨著對(duì)象的創(chuàng)建而創(chuàng)建,伴隨著對(duì)象的銷毀而銷毀。局部變量,生命周期較短,伴隨著它的代碼塊的執(zhí)行而創(chuàng)建,伴隨著代碼塊的結(jié)束而銷毀。即在一次方法調(diào)用過程中*///p1.say();//當(dāng)執(zhí)行say方法時(shí),say方法的局部變量比如name,會(huì)創(chuàng)建,當(dāng)say執(zhí)行完畢后//name局部變量就銷毀,但是屬性(全局變量)仍然可以使用//T t1 = new T();t1.test(); //第1種跨類訪問對(duì)象屬性的方式
?t1.test2(p1);//第2種跨類訪問對(duì)象屬性的方式
?}
}
?
class T {
?//全局變量/屬性:可以被本類使用,或其他類使用(通過對(duì)象調(diào)用)public void test() {Person p1 = new Person();System.out.println(p1.name);//jack}
?public void test2(Person p) {System.out.println(p.name);//jack}
}
?
class Person {//細(xì)節(jié): 屬性可以加修飾符(public protected private..)// 局部變量不能加修飾符public int age = 20;
?String name = "jack";
?public void say() {//細(xì)節(jié) 屬性和局部變量可以重名,訪問時(shí)遵循就近原則String name = "king";System.out.println("say() name=" + name);}
?public void hi() {String address = "北京";//String address = "上海";//錯(cuò)誤,重復(fù)定義變量String name = "hsp";//可以}
}
構(gòu)造方法/構(gòu)造器
基本語法
[修飾符] 方法名(形參列表){
方法體;
}
說明:
- 1)構(gòu)造器的修飾符可以默認(rèn), 也可以是 public protected private
- 2)構(gòu)造器沒有返回值
- 3)方法名 和類名字必須一樣
- 4)參數(shù)列表 和 成員方法一樣的規(guī)則
- 5)構(gòu)造器的調(diào)用, 由系統(tǒng)完成
?基本介紹
構(gòu)造方法又叫構(gòu)造器(constructor),是類的一種特殊的方法,它的主要作用是完成對(duì)新對(duì)象的初始化。它有幾個(gè)特點(diǎn):
- 1)方法名和類名相同
- 2)沒有返回值
- 3)在創(chuàng)建對(duì)象時(shí),系統(tǒng)會(huì)自動(dòng)的調(diào)用該類的構(gòu)造器完成對(duì)象的初始化。
注意事項(xiàng)和使用細(xì)節(jié)
- 一個(gè)類可以定義多個(gè)不同的構(gòu)造器,即構(gòu)造器重載比如:我們可以再給Person類定義一個(gè)構(gòu)造器,用來創(chuàng)建對(duì)象的時(shí) 候,只指定人名不需要指定年齡
- 構(gòu)造器名和類名要相同
- 構(gòu)造器沒有返回值
- 構(gòu)造器是完成對(duì)象的初始化,并不是創(chuàng)建對(duì)象
- 在創(chuàng)建對(duì)象時(shí),系統(tǒng)自動(dòng)的調(diào)用該類的構(gòu)造方法
- 如果程序員沒有定義構(gòu)造器,系統(tǒng)會(huì)自動(dòng)給類生成一個(gè)默認(rèn)無參構(gòu)造器(也叫默認(rèn)構(gòu)造器),比如 Dog (){},使用javap指令 反編譯看看
- 一旦定義了自己的構(gòu)造器,默認(rèn)的構(gòu)造器就覆蓋了,就不能再使用默認(rèn)的無參構(gòu)造器,除非顯式的定義一下,即:Dog()){}寫(這點(diǎn)很重要
public class ConstructorDetail {
?//編寫一個(gè)main方法public static void main(String[] args) {Person p1 = new Person("king", 40);//第1個(gè)構(gòu)造器Person p2 = new Person("tom");//第2個(gè)構(gòu)造器
?Dog dog1 = new Dog();//使用的是默認(rèn)的無參構(gòu)造器
?}
}
class Dog {//如果程序員沒有定義構(gòu)造器,系統(tǒng)會(huì)自動(dòng)給類生成一個(gè)默認(rèn)無參構(gòu)造器(也叫默認(rèn)構(gòu)造器)//使用javap指令 反編譯看看/*默認(rèn)構(gòu)造器Dog() {}*///一旦定義了自己的構(gòu)造器,默認(rèn)的構(gòu)造器就覆蓋了,就不能再使用默認(rèn)的無參構(gòu)造器,//除非顯式的定義一下,即: Dog(){} 寫 (這點(diǎn)很重要)//public Dog(String dName) {//...}Dog() { //顯式的定義一下 無參構(gòu)造器
?}
}
?
class Person {String name;int age;//默認(rèn)0//第1個(gè)構(gòu)造器public Person(String pName, int pAge) {name = pName;age = pAge;}//第2個(gè)構(gòu)造器, 只指定人名,不需要指定年齡public Person(String pName) {name = pName;}
}
對(duì)象創(chuàng)建的流程分析
學(xué)習(xí)完構(gòu)造器后,我們類的定義就應(yīng)該更加完善了
this 關(guān)鍵字
什么是this?
在編程中,this
?關(guān)鍵字是一個(gè)特殊的標(biāo)識(shí)符,它被自動(dòng)定義在函數(shù)和方法的執(zhí)行上下文中。this
?的值通常指向調(diào)用該函數(shù)的對(duì)象,也就是函數(shù)運(yùn)行時(shí)所處的對(duì)象上下文。
public class This01 {
?//編寫一個(gè)main方法public static void main(String[] args) {
?Dog dog1 = new Dog("大壯", 3);System.out.println("dog1的hashcode=" + dog1.hashCode());//dog1調(diào)用了 info()方法dog1.info();
?System.out.println("============");Dog dog2 = new Dog("大黃", 2);System.out.println("dog2的hashcode=" + dog2.hashCode());dog2.info();}
}
?
class Dog{ //類
?String name;int age;// public Dog(String dName, int dAge){//構(gòu)造器// name = dName;// age = dAge;// }//如果我們構(gòu)造器的形參,能夠直接寫成屬性名,就更好了//但是出現(xiàn)了一個(gè)問題,根據(jù)變量的作用域原則//構(gòu)造器的name 是局部變量,而不是屬性//構(gòu)造器的age 是局部變量,而不是屬性//==> 引出this關(guān)鍵字來解決public Dog(String name, int age){//構(gòu)造器//this.name 就是當(dāng)前對(duì)象的屬性namethis.name = name;//this.age 就是當(dāng)前對(duì)象的屬性agethis.age = age;System.out.println("this.hashCode=" + this.hashCode());}
?public void info(){//成員方法,輸出屬性x信息System.out.println("this.hashCode=" + this.hashCode());System.out.println(name + "\t" + age + "\t");}
}
?
深入理解this
為了進(jìn)一步理解this,我們?cè)倏匆粋€(gè)案例(This01.java)
this 的注意事項(xiàng)和使用細(xì)節(jié)
ThisDetail.java
- 1) this 關(guān)鍵字可以用來訪問本類的屬性、方法、構(gòu)造器
- 2) this 用于區(qū)分當(dāng)前類的屬性和局部變量
- 3) 訪問成員方法的語法:this.方法名(參數(shù)列表);
- 4)訪問構(gòu)造器語法:this(參數(shù)列表);注意只能在構(gòu)造器中使用(即只能在構(gòu)造器中訪問另外一個(gè)構(gòu)造器,必須放在第一 條語句)
- 5) this不能在類定義的外部使用,只能在類定義的方法中使用。
this的課堂案例
TestPerson.java
定義Person類,里面有name、age屬性,并提供compareTo比較方法,用于判斷是否和另一個(gè)人相等,提供測試類TestPerson 用于測試,名字和年齡完全一樣,就返回true,否則返回false
public class TestPerson {
?//編寫一個(gè)main方法public static void main(String[] args) {
?Person p1 = new Person("mary", 20);Person p2 = new Person("mary", 20);
?System.out.println("p1和p2比較的結(jié)果=" + p1.compareTo(p2));}
}
?
/*
定義 Person 類,里面有 name、age 屬性,并提供 compareTo 比較方法,用于判斷是否和另一個(gè)人相等,名字和年齡完全一樣,就返回 true, 否則返回 false
?*/
class Person {String name;int age;//構(gòu)造器public Person(String name, int age) {this.name = name;this.age = age;}//compareTo比較方法public boolean compareTo(Person p) {//名字和年齡完全一樣// if(this.name.equals(p.name) && this.age == p.age) {// return true;// } else {// return false;// }return this.name.equals(p.name) && this.age == p.age;}
}