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