Day1
Java語言平臺的版本
-Java SE(標準版) 為開發(fā)普通桌面和商務(wù)程序提供解決方案 是Java ME 和 Java EE 的基礎(chǔ),可以完成一些桌面應(yīng)用程序的開發(fā)
-Java ME (小型版) 為開發(fā)電子消費產(chǎn)品和嵌入式設(shè)備提供解決方案
-Java EE(企業(yè)版) 為開發(fā)企業(yè)環(huán)境下的應(yīng)用程序提供一套解決方案问欠,該技術(shù)主要包括Select,jsp,主要針對Web應(yīng)用開發(fā)
Java語言的特點
簡單性从诲,解釋性,面向?qū)ο蠡肿牛咝阅埽植际教幚恚嗑€程,健壯性螃壤,動態(tài),結(jié)構(gòu)性集漾,安全性却汉,開源,跨平臺(JVM相當(dāng)于翻譯食侮,Java可以跨平臺号涯,JVM不可以跨平臺,針對每個操作系統(tǒng)都有對應(yīng)的JVM)
第一個程序HelloWorld
class HelloWord{
public static void main(String[] args) {
System.out.println("hello锯七,world");
}
}
寫程序的步驟
/*
需求: 在控制臺上輸出Hello,World
分析:
1.要寫一個Java程序链快,必須先定義一個類
2.程序要想運行,必須有main函數(shù)
3.輸出一個語句必須用到輸出語句
實現(xiàn):
1.定義類用到class眉尸,后邊跟類名
2.main函數(shù)的格式是固定的
public static void main(String[] args){
表達式或語句
}
3.輸出語句的格式是固定的
System.out.println("hello,world"); "hello,world"內(nèi)容可變
*/
//這是我的第一個程序域蜗,輸出hello,world
class HelloWord{
//定義main方法噪猾,main是程序的入口霉祸,被JVM自動調(diào)用
public static void main(String[] args){
//輸出語句
System.out.println("hello,world");
}
}
Day2
原碼反碼和補碼
原碼 反碼 補碼
正數(shù) 二進制 與原碼相同 與原碼相同
負數(shù) 二進制 將原碼取反 將反碼末位+1
負數(shù)將反碼轉(zhuǎn)換成原碼需要先減一在取反
數(shù)據(jù)類型
數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型(類,接口袱蜡,數(shù)組)
基本數(shù)據(jù)類型(4類8種)
占用字節(jié) 范圍
整數(shù)
byte 1 ∷坎洹-128到127
shor 2 -2的15次方到2的15次方-1
int 4 -2的31次方到2的31次方-1
long 8 -2的63次方到2的63次方-1
浮點數(shù)
float 4 -3.043E38到3.403E38
double 8 ∑阂稀-1.798E308到1.798E308
字符
cha r ”即2
布爾
boolean 1
在定義Long或者Float類型的數(shù)據(jù)時,要在數(shù)據(jù)后邊加L或F
整數(shù)默認的類型為Int,浮點數(shù)默認的為double
byte和short在定義的時候默認接收的是一個整數(shù),如果不在自己的范圍內(nèi)就報錯
命名規(guī)則
常見的命名規(guī)則:見名知意
舉例:我要定義一個學(xué)生類
class Student {}
class S{}
包:其實就是文件夾敏晤,用于把相同的類名進行區(qū)分
全部小寫
單級: zhangsan
多級:cn.baidu
類或者接口:
一個單詞:單詞的首字母必須大寫
舉例:Student,Dog
多個單詞:每個單詞的首字母必須大寫
舉例:HelloWorld,StudentName
方法或者變量:
一個單詞:單詞的首字母小寫
舉例:main,age
多個單詞:從第二個單詞開始贱田,每個單詞的首字母大寫
舉例:studentAge,showAllNames()
常量:
一個單詞:全部大寫
舉例:PI
多個單詞:每個字母都大寫,用_隔開
舉例:STUDENT_MAX_AGE
默認數(shù)據(jù)類型轉(zhuǎn)換
是從小的范圍到大的范圍進行轉(zhuǎn)換
byte,short,char→int→long→folat→double
注意:byte,short,long不可以相互轉(zhuǎn)換,在運算時默認轉(zhuǎn)換成int進行運算
運算過程種有范圍大的數(shù)據(jù)類型,結(jié)果一定是范圍大的數(shù)據(jù)類型
例:3(int)+3.55(double)結(jié)果是6.55(double),賦值時一定要注意
強制數(shù)據(jù)類型轉(zhuǎn)換
格式:目標數(shù)據(jù)類型 變量∽炱ⅰ=(目標數(shù)據(jù)類型)(被轉(zhuǎn)換的數(shù)據(jù));
例: int a = (int)(3+3.2); 結(jié)果為6
注意:強制類型轉(zhuǎn)換會損失精度,3+3.2應(yīng)該等于6.2,但int只能取整數(shù)部分
//下列兩個語句那個會編譯報錯,為什么
byte b1 = 3;
byte b2 = 4;
byte b;
b = b1 + b2;//會報錯,在運算時,byte,short,char會轉(zhuǎn)換成int類型進行運算,Int占4位,賦值給byte類型會報錯
b = 3+4;//不會報錯,先將3+4的運算結(jié)果算出來,再看運算結(jié)果是否在byte 數(shù)據(jù)范圍內(nèi),若在,則不報錯
//將130賦值給byteb是否有問題?如果想賦值應(yīng)該怎么寫?結(jié)果是多少?
byte b = 130;//會報錯,因為byte的取值范圍為-127到128
byte b = (byte)(130);//可以進行強制類型轉(zhuǎn)換
//結(jié)果為-126
/*
分析過程
要想知道為什么結(jié)果為-126,就需要知道數(shù)據(jù)在計算機是如何進行運算的
計算機中的數(shù)據(jù)是通過補碼進行運算的
獲取130的二進制,130為整數(shù),默認占4個字節(jié)
00000000 00000000 0000000 10000010
這是130的原碼,正數(shù)的原碼反碼補碼都相同,所以這也是130的補碼
byte b 為字節(jié),默認占1位字節(jié),要對130的補碼進行截取
得到 10000010 這是補碼,且第一位為0,所以為負數(shù),將負數(shù)的補碼轉(zhuǎn)換成原碼
得到11111110 即-126
*/
輸出的幾種形式
System.out.println("hello"+'a'+1);//結(jié)果為helloa1
System.out.println('a'+1+"hello");//結(jié)果為98hello
//因為字符串?dāng)?shù)據(jù)和其他數(shù)據(jù)做+,結(jié)果依舊是字符串類型
//這里的+不是加法運算,而是作為連接符
System.out.println("5+5="+5+5);//結(jié)果為5+5=55,"5+5="為字符串,所以+為連接符
System.out.println(5+5+"=5+5");//結(jié)果為10=5+5,從左到右進行運算
記住'a'的Ascll碼為97,'A'的Ascll碼為65,'0'的Ascll碼為48
算數(shù)運算符
++,--運算符
單獨使用時:
放在變量前邊和后邊的用法是一樣的
參入運算時:
放在變量的前邊時,先進行自增或自減,在參入運算
放在變量的后邊時,先參入運算,在進行自增或自減
作用:對變量進行自增1或者自減1
賦值運算符
=,+=,-=,*=,/=,%=
=是基本的賦值運算符,其他的是拓展的賦值運算符
+=就是將左邊和右邊相加然后賦值給左邊
例:a += 3;就是將a+3的值賦值給a
//拓展的賦值運算符隱含了強制類型轉(zhuǎn)
short s ;
s = s + 1;//會報錯,因為short在運算時會轉(zhuǎn)換成int類型,所以將int賦值給short是錯誤的
s+=1;//不會報錯,拓展賦值運算符相當(dāng)于 s = (s的數(shù)據(jù)類型)(s+1);進行強制類型轉(zhuǎn)換
關(guān)系運算符
不管進行什么操作,結(jié)果一定是布爾類型
邏輯運算符
邏輯運算符用于連接布爾類型的表達式
&與 一假即假
|或 一真即真
^異或 相同為假,不同為真
&和&&的區(qū)別:
&的左邊為假時,則不對右邊進行運算,直接忽略
&&不管左邊是否為假,右邊都要進行運算
|與||同上
位運算符
直接對二進制進行運算男摧,對數(shù)的補碼進行操作
&與位運算:有0則0;|或位運算:有1則1译打;^位異或運算:相同為0耗拓,不同為1;
一個數(shù)與兩個相同的數(shù)進行異或扶平,結(jié)果不變
例:a ^ b ^ b; 結(jié)果為a
<<相當(dāng)于把左邊的數(shù)據(jù)乘以2的移動次冪帆离,>>相當(dāng)于把左邊的數(shù)據(jù)除以2的移動次冪
操作時注意是對補碼進行運算,換算成二進制是原碼结澄,注意負數(shù)哥谷;
//交換兩個整數(shù)的位置
int a = 10,b = 20;
//第一種方法,利用空變量進行交換(開發(fā))
int c;
c = a;
a = b;
b = c;
//第二種方法岸夯,利用位異或?qū)崿F(xiàn)(面試)
a = a ^ b;//不計算,直接帶到下邊
b = a ^ b;//b = a ^ b ^ b; 相當(dāng)于 b = a;
a = a ^ b;// b = a ^ b ^ a;因為上邊 b = a;
//第三種方法们妥,利用變量加法
a = a+ b;//不計算猜扮,直接帶入下邊
b = a - b;// b = a + b - b;得 b = a
a = a - b;// a = a + b - a 得 a = b
//第四種方法,一句話搞定
b = (a+b) - (a = b);//相當(dāng)于把b賦給a,得到 b = (a+b) - b
優(yōu)先級
口訣單目乘除為關(guān)系监婶,邏輯三目后賦值旅赢。
Day3
三目運算符
格式:(關(guān)系表達式)?表達式1:表達式2;
如果表達式為真,則取表達式1的值惑惶,如果為假煮盼,則取表達式2的值
//求兩個數(shù)中的最大值
int a = 3,b = 5;
int max = (a>b)?a:b;//如果a大于b,則把a的值給max,如果a不大于b,則把b的值給max
鍵盤錄入數(shù)據(jù)
第一步導(dǎo)包:在所有的class定義之上
import java.util.Scanner;
第二步:創(chuàng)建對象:
Scanner sc = new Scanner(System.in);
第三步:接收數(shù)據(jù):
int a = sc.nextInt();
nextInt只能獲取Int類型的數(shù)带污,可以有nextFloat,nextDouble等
import java.util.Scanner;//導(dǎo)包
class Get Keyboard{
public static void main(String[] agrs){
Scanner sc = new Scanner(System.in);//創(chuàng)建對象sc
int a;
a = sc.nextInt();//用a接收鍵盤輸入的數(shù)據(jù)
System.out.println("從鍵盤獲取的是"+a);
}
}
流程控制語句
-順序結(jié)構(gòu)
-選擇結(jié)構(gòu)
-循環(huán)結(jié)構(gòu)
順序結(jié)構(gòu)
最基本的流程控制僵控,就是按照從上往下執(zhí)行,先寫的先執(zhí)行
選擇結(jié)構(gòu)
也稱為分支結(jié)構(gòu)鱼冀,選擇結(jié)構(gòu)有特定的語法規(guī)則报破,代碼要執(zhí)行具體的邏輯運算進行判斷,邏輯運算的結(jié)果有兩個千绪,所以產(chǎn)生選擇充易,按照不同的選擇執(zhí)行不同的代碼。
java提供了兩種選擇結(jié)構(gòu)語句
-if語句
-switch語句
if語句
if語句有三種格式
/*
if語句第一種格式:
if(關(guān)系表達式) {
語句體
}
執(zhí)行流程
首先判斷關(guān)系表達式看其結(jié)果是true還是false
如果是true就執(zhí)行語句體
如果是false就不執(zhí)行語句體
*/
int a = 20;
int b = 10;
if(a>b){ //先判斷表達式a>b的結(jié)果是真還是假
System.out.println("a大于b");//如果為真則執(zhí)行輸出語句荸型,為假則不執(zhí)行
}
/*
if語句第二種格式:
if(關(guān)系表達式) {
語句體1;
}else {
語句體2;
}
執(zhí)行流程
首先判斷關(guān)系表達式看其結(jié)果是true還是false
如果是true就執(zhí)行語句體1
如果是false就執(zhí)行語句體2
*/
int a = 20;
int b = 10;
if(a>b){ //先判斷表達式a>b的結(jié)果是真還是假
System.out.println("a大于b");//如果為真則執(zhí)行if語句體盹靴,為假則輸出else語句體
}else {
System.out.println("b大于a");
}
/*
if語句第三種格式:
if(關(guān)系表達式1) {
語句體1;
}else if (關(guān)系表達式2) {
語句體2;
}
…
else {
語句體n+1;
}
首先判斷關(guān)系表達式1看其結(jié)果是true還是false
如果是true就執(zhí)行語句體1
如果是false就繼續(xù)判斷關(guān)系表達式2看其結(jié)果是true還是false
如果是true就執(zhí)行語句體2
如果是false就繼續(xù)判斷關(guān)系表達式…看其結(jié)果是true還是false
…
如果沒有任何關(guān)系表達式為true,就執(zhí)行語句體n+1
int a = 20;
int b = 10;
if(a>b){ //先判斷表達式a>b的結(jié)果是真還是假
System.out.println("a大于b");//為真則執(zhí)行if語句體
}else if(b>a) {//為假則判斷else if的表達式是真還是假
System.out.println("b大于a");
}else {
System.out.println("a等于b");
}
*/
if語句的使用場景
針對結(jié)果是boolean類型的判斷
針對一個范圍的判斷
針對幾個常量值的判斷
switch語句
/*
switch語句格式:
switch(表達式) {
case 值1:
語句體1;
break;
case 值2:
語句體2;
break;
…
default:
語句體n+1;
break;
}
*/
switch語句使用場景
針對幾個常量值的判斷
循環(huán)結(jié)構(gòu)
循環(huán)語句的組成
初始化語句:
一條或者多條語句帆疟,這些語句完成一些初始化操作
判斷條件語句:
這是一個boolean 表達式鹉究,這個表達式能決定是否執(zhí)行循環(huán)體
循環(huán)體語句:
這個部分是循環(huán)體語句,也就是我們要多次做的事情
控制條件語句:
這個部分在一次循環(huán)體結(jié)束后踪宠,下一次循環(huán)判斷條件執(zhí)行前執(zhí)行。通過用于控制循環(huán)條件中的變量妈嘹,使得循環(huán)在合適的時候結(jié)束
for循環(huán)語句格式
格式:
for(初始化語句;判斷條件語句;控制條件語句) {
循環(huán)體語句;
}
執(zhí)行流程
1.執(zhí)行初始化語句
2.執(zhí)行判斷條件語句柳琢,看其結(jié)果是true還是false
如果是false,循環(huán)結(jié)束
如果是true润脸,繼續(xù)執(zhí)行
3.執(zhí)行循環(huán)體語句
4.執(zhí)行控制條件語句
5.回到2繼續(xù)
//用for循環(huán)求1-10的和
int num = 0,i;
for(i = 0;i < 10;i++){
num = num +i;
}
System.out.println("1-10的和為"+num);
//求100-1000之間有哪些水仙花數(shù)
int i,x,y,z; //水鮮花數(shù)是一種三位數(shù),其各個數(shù)之立方和等于該數(shù)
for(i = 100;i < 1000;i++){
x = i/100; //125整除100,得1
y = i/10%10; //125整除10,得12然后在取余10得2,即125的十位
z = i%10; //125取余10得5
if(i == x*x*x + y*y*y* +z*z*z){
System.out.println("水仙花數(shù)"+i);
}
}
while循環(huán)語句
格式:
基本格式
while(判斷條件語句) {
循環(huán)體語句;
}
擴展格式
初始化語句;
while(判斷條件語句) {
循環(huán)體語句;
控制條件語句;
}
//利用while循環(huán)求一張0.01M的紙折疊多少次可以超過珠穆朗瑪峰8848M
double i = 0.01;
int j=0;//表示折疊的次數(shù)
while (i <= 8848){ //只要i小于8848就一直執(zhí)行,直到i大于8848結(jié)束
j++;
i = i*2;
}
System.out.println("折疊了"+j+"次");
do while循環(huán)
格式:
基本格式
do {
循環(huán)體語句;
}while((判斷條件語句);
擴展格式
初始化語句;
do {
循環(huán)體語句;
控制條件語句;
} while((判斷條件語句);
do while 循環(huán)最少會執(zhí)行一次循環(huán)體,while,for則是必須條件為真才會執(zhí)行
循環(huán)練習(xí)
/*
輸出 *
**
***
****
*****
分析:輸出5行*,依次增加數(shù)量
*/
for(int i = 0;i < 5;i++){ //控制外層循環(huán)5次
for(int j = 0;j < i+1;j++){ //控制*輸出的個數(shù)每次加1
System.out.print("*"); //print 輸出完不進行換行
}
System.out.println(); //println輸出完進行換行,可以輸出空進行換行
}
//輸出九九乘法表
for (int i = 1; i < 10; i++) {
for (int j = 1; j < i+1; j++) {
System.out.print(i+"*"+j+"="+i*j+"\t");
}
System.out.println(" ");
}
跳轉(zhuǎn)控制語句:break,continue,return
break:在switch結(jié)構(gòu)和循環(huán)中使用,作用是跳出并結(jié)束本輪循環(huán)
for(int i = 0;i < 5;i++){
if(i == 2){
break;
}
System.out.print("你好"); //結(jié)果只輸出兩個你好,因為在i =2也就是第三次循環(huán)的時候,符合if的條件跳出
}
break跳出多層循環(huán)的用法
要想跳出多層循環(huán),就必須帶標簽的跳出
標簽的格式: 標簽名:循環(huán)語句
for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){
System.out.print("*"); //輸出一個四行四列的星號
if(j == 2){
break; //加上break,輸出四行三列的星號,因為if語句只是在j等于2的時候結(jié)束j的循環(huán)
}
}
System.out.println(); //換行
}
//要想退出多層循環(huán)就要用標簽
out:
for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){
System.out.println("*");
if(j == 2){
break out; //out:標簽的作用就是break直接跳到out:處,且不在執(zhí)行循環(huán)
}
}
System.out.println(); //換行
}
continue:在循環(huán)中使用,作用是跳出本次循環(huán),但繼續(xù)執(zhí)行下一次循環(huán)
for(int i = 1;i < 5;i++){
if(i == 2){
continue; //輸出結(jié)果為1,3,4,因為在i等于2的時候,符合if語句,所以跳出本次循環(huán),但不結(jié)束循環(huán)
}
System.out.println(i);
}
continue也可以跳出多層循環(huán),參考break;
return:不是為了跳轉(zhuǎn)出循環(huán)體柬脸,更常用的功能是結(jié)束一個方法,也就是退出一個方法,跳轉(zhuǎn)到上層調(diào)用的方法
Day4
方法
完成特定功能的代碼塊毙驯,其他語言稱為函數(shù)
格式:
修飾符 返回值類型 方法名(參數(shù)類型 參數(shù)名1,參數(shù)類型 參數(shù)名2...) {
方法體語句;
return 返回值;
}
public static int sum(int a,int b){
int sum = a + b;
return sum;
}
詳細解釋:
修飾符:目前就用 public static
返回值類型:就是功能結(jié)果的數(shù)據(jù)類型
方法名:符合命名規(guī)則即可倒堕。方便我們的調(diào)用
參數(shù):
實際參數(shù):就是實際參與運算的
形式參數(shù);就是方法定義上的爆价,用于接收實際參數(shù)的
參數(shù)類型:就是參數(shù)的數(shù)據(jù)類型
參數(shù)名:就是變量名
方法體語句:就是完成功能的代碼
return:結(jié)束方法的垦巴。
返回值:就是功能的結(jié)果媳搪,由return帶給調(diào)用者
要想寫好一個方法,就必須明確兩個東西:
-返回值類型
結(jié)果的數(shù)據(jù)類型
-參數(shù)列表
你要傳遞幾個參數(shù)骤宣,以及每個參數(shù)的數(shù)據(jù)類型
方法調(diào)用格式(有返回值的):
-單獨調(diào)用:沒意義
-輸出調(diào)用:寫在輸出語句中
-賦值調(diào)用:調(diào)用后賦值給一個變量,方便后期使用
無返回值類型的只能單獨調(diào)用
方法調(diào)用圖解
方法的注意事項:
-方法不調(diào)用不執(zhí)行
-方法與方法是平級關(guān)系秦爆,不能嵌套定義
-方法定義的時候參數(shù)之間用逗號隔開
-方法調(diào)用的時候不用在傳遞數(shù)據(jù)類型
-如果方法有明確的返回值,一定要有return帶回一個值
方法重載
在同一個類中憔披,方法名相同等限,參數(shù)列表不同,與返回值類型無關(guān)
參數(shù)列表不同:
-參數(shù)個數(shù)不同
-參數(shù)類型不同
方法重載特點
-與返回值類型無關(guān),只看方法名和參數(shù)列表
-在調(diào)用時芬膝,虛擬機通過參數(shù)列表的不同來區(qū)分同名方法
public static void main(String[] args) {
//方法重載,比較int和float數(shù)據(jù)是否相同
int a = 3;
int b = 4;
int c = 5;
boolean flag = compare(a, b); //根據(jù)給的參數(shù)的類型去匹配compare方法的類型
System.out.println(flag); //輸出int false
float f = 2.2f;
float f1 = 2.2f;
boolean flag1 = compare(f,f1);
System.out.println(flag1); //輸出float true
}
public static boolean compare(int a,int b,int c){ //比較int
System.out.println("int");
return (a ==b);
}
public static boolean compare(float a,float b) { //比較float
System.out.println("float");
return (a == b);
}
數(shù)組
數(shù)組是存儲同一種數(shù)據(jù)類型多個元素的集合,也可以看成是一個容器
數(shù)組既可以存儲基本數(shù)據(jù)類型望门,也可以存儲引用數(shù)據(jù)類型
數(shù)組定義:
-格式1:數(shù)據(jù)類型[] 數(shù)組名;
int [] arr;
-格式2:數(shù)據(jù)類型 數(shù)組名[];
int arr [];
數(shù)組的初始化:
-動態(tài)初始化:初始化時只指定數(shù)組長度,由系統(tǒng)為數(shù)組分配初始值
格式:數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[數(shù)組長度];
數(shù)組長度就是數(shù)組中元素的個數(shù)
int [] arr = new int [5]; //定義了一個int類型的數(shù)組,這個數(shù)組可以存放3個int類型的值
-靜態(tài)初始化:初始化時指定每個數(shù)組元素的初始值锰霜,由系統(tǒng)決定數(shù)組長度
格式:數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[]{元素1,元素2,…};
int [] arr = new int []{1,2,3,4,5};
//可以簡寫為:
int [] arr = {1,2,3,4,5};
數(shù)組的長度可以用數(shù)組名.length表示
int [] arr = {1,2,3,4,5};
arr.length 就等于5
java的內(nèi)存分配
Java 程序在運行時筹误,需要在內(nèi)存中的分配空間。為了提高運算效率锈遥,就對空間進行了不同區(qū)域的劃分纫事,因為每一片區(qū)域都有特定的處理數(shù)據(jù)方式和內(nèi)存管理方式
-棧 存儲局部變量
-堆 存儲new出來的東西
-方法區(qū) (面向?qū)ο?
-本地方法區(qū) (和系統(tǒng)相關(guān))
-寄存器 (給CPU使用)
數(shù)組遍歷及輸出
//數(shù)組的遍歷及輸出
int [] arr = {1,2,5,6,8,7,1,5};
for (int i = 0; i < arr.length; i++) {
System.out.println("第"+(i+1)+"個元素為"+arr[i]);
//求一個數(shù)在數(shù)組中第一次出現(xiàn)的位置
int [] arr = {1,2,5,6,8,7,1,5};
System.out.println("請輸入一個數(shù)");
Scanner sc = new Scanner(System.in); //在類上導(dǎo)包
int num = sc.nextInt(); //獲取鍵盤數(shù)據(jù)
boolean flag = true; //判斷
for (int i = 0; i < arr.length; i++) {
if (num == arr[i]) {
System.out.println("該數(shù)據(jù)首次出現(xiàn)在第" + (i + 1) + "個位置");
flag = false; //如果輸入的數(shù)據(jù)在數(shù)組中,則把判斷位變?yōu)閒lase
break;
}
}
if (flag){ //對判斷位進行判斷,若為真,則說明if語句未執(zhí)行
System.out.println("該數(shù)據(jù)沒有在數(shù)組中");
{
冒泡排序
//從小到大排列數(shù)組
int [] arr = {1,2,5,6,8,7,9,15};
int tmp = 0; //中間變量
for (int i = 0; i < arr.length-1; i++) { //外層循環(huán)控制比較次數(shù),8個數(shù)需要7輪比較完
for (int j = 0; j < arr.length-1; j++) { //內(nèi)層循環(huán)控制每次比較的次數(shù),8個數(shù)需要7次比較
if (arr[i] > arr[i+1]){ //如果前邊的數(shù)比后邊的數(shù)大,就換位置
tmp = arr[i]; //中間變量,交換位置
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
數(shù)組常見錯誤
數(shù)組索引越界 ArrayIndexOutOfBoundsException
訪問到了數(shù)組中的不存在的索引時發(fā)生
空指針異常 NullPointerException
數(shù)組引用沒有指向?qū)嶓w,卻在操作實體中的元素時
Day5
二維數(shù)組
格式1:
數(shù)據(jù)類型[][] 數(shù)組名 = new 數(shù)據(jù)類型[m][n];
m:表示這個二維數(shù)組有多少個一維數(shù)組
n:表示每一個一維數(shù)組的元素有多少個
注意:
以下格式也可以表示二維數(shù)組:
∷摹-數(shù)據(jù)類型 數(shù)組名[][] = new 數(shù)據(jù)類型[m][n];
±龌獭-數(shù)據(jù)類型[] 數(shù)組名[] = new 數(shù)據(jù)類型[m][n];
class Array2 {
public static void main(String[] args) {
//定義一個二維數(shù)組
int[][] arr = new int[3][2];
//定義了一個二維數(shù)組arr
//這個二維數(shù)組有3個一維數(shù)組的元素
//每一個一維數(shù)組有2個元素
//輸出二維數(shù)組名稱
System.out.println(arr); //地址值 [[I@175078b
//輸出二維數(shù)組的第一個元素一維數(shù)組的名稱
System.out.println(arr[0]); //地址值 [I@42552c
System.out.println(arr[1]); //地址值 [I@e5bbd6
System.out.println(arr[2]); //地址值 [I@8ee016
//輸出二維數(shù)組的元素
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
}
}
格式2:
數(shù)據(jù)類型[][] 數(shù)組名 = new 數(shù)據(jù)類型[m][];
m:表示這個二維數(shù)組有多少個一維數(shù)組
列數(shù)沒有給出,可以動態(tài)的給,這一次是一個變化的列數(shù)
格式3:
基本格式:
數(shù)據(jù)類型[][] 數(shù)組名 = new 數(shù)據(jù)類型[][]{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
簡化版格式:
數(shù)據(jù)類型[][] 數(shù)組名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
舉例:
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[][] arr = {{1,2,3},{4,5},{6}};
二維數(shù)組的遍歷
public class Arr2Print {
public static void main(String[] args) {
//定義一個二維數(shù)組進行遍歷
int [] [] arr = {{1,2,3},{4,5},{6}};
//利用每個數(shù)組的長度進行遍歷
for (int i = 0; i < arr[0].length; i++) {
System.out.print(arr[0][i]+" ");
}
System.out.println();
for (int i = 0; i < arr[1].length; i++) {
System.out.print(arr[1][i]+" ");
}
System.out.println();
for (int i = 0; i < arr[2].length; i++) {
System.out.print(arr[2][i]+" ");
}
System.out.println();
//可以用嵌套
for (int i = 0; i < arr.length; i++) { //arr.length代表二維數(shù)組的長度爬立,也就是一維數(shù)組的個數(shù)
for (int j = 0; j < arr[i].length; j++) { //arr[i].length代表每個一維數(shù)組的長度钾唬,i從0~2
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
打印楊輝三角
public class YangHui {
/**
需求:需求:打印楊輝三角形(行數(shù)可以鍵盤錄入)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
分析:楊輝三角的第一列和最后一列都是1
從第三行開始,每一個數(shù)據(jù)都是上一列的前一個數(shù)據(jù)和本列之和
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入行數(shù)");
int m = sc.nextInt();
int [][] arr= new int [m][m];
for (int i = 0; i < arr.length; i++) { //使第一列和最后一列都為1
arr[i][0] = 1;
arr[i][i] = 1;
}
//從第三行開始侠驯,每一個數(shù)據(jù)都是上一列的前一個數(shù)據(jù)和本列之和
for (int i = 2; i < arr.length; i++) { //從第三行開始抡秆,所以i= 2
//因為第一列已經(jīng)賦值了1,所以y從1開始
//因為最后一列賦值了1吟策,所以j<arr[i].length - 1
for (int j = 1; j < arr[i].length-1; j++) {
//arr[i][j]表示當(dāng)前數(shù)據(jù)儒士, i-1為上一行,j-1為前一列
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
for (int i = 0; i < arr.length; i++) { //遍歷數(shù)組
for (int j = 0; j <= i; j++) { //放照九九乘法表內(nèi)循環(huán)
System.out.print(arr[i][j]+" ");
}
System.out.println( );
}
}
}
將一個整數(shù)的每一位寫入到一個數(shù)組中
Scanner sc = new Scanner(System.in);
int num = sc.nextInt(); //從鍵盤獲取一個數(shù)據(jù)
int index = 0; //因為不知道獲取了幾位數(shù)檩坚,所以定義一個索引
while (num > 0){ //假設(shè)num12345,num = 1234,num = 123,num = 12,num = 1,num = 0,不符合循環(huán)條件
arr[index] = num%10; //arr[0] = 5,arr[1] = 4,arr[2] = 3,arr[3] =2,arr[4] = 1
num/=10;//num = 1234,num = 123,num = 12,num = 1,num = 0
index++;//index = 1,index = 2,index = 3,index = 4,index =5,index為索引表示數(shù)組長度為5
}
//打印
for (int i = 0; i < index; i++) { //index為索引着撩,及數(shù)組長度
System.out.print(arr[i]+" ");
//打印出5 4 3 2 1,但是數(shù)據(jù)是逆序存入數(shù)組的匾委,可以在定義一個數(shù)組對arr進行逆序
public class Text1 {
public static void main(String[] args) {
/*
* 某個公司采用公用電話傳遞數(shù)據(jù)信息拖叙,數(shù)據(jù)是小于8位的整數(shù),為了確保安全赂乐,
在傳遞過程中需要加密薯鳍,加密規(guī)則如下:
首先將數(shù)據(jù)倒序,然后將每位數(shù)字都加上5挨措,再用和除以10的余數(shù)代替該數(shù)字挖滤,
最后將第一位和最后一位數(shù)字交換崩溪。 請任意給定一個小于8位的整數(shù),
然后壶辜,把加密后的結(jié)果在控制臺打印出來悯舟。
* 分析:小于8位的整數(shù):定義int類型變量,從鍵盤獲取砸民,Scanner
* 將數(shù)據(jù)倒序抵怎,就要獲取輸入每一位的數(shù),存到數(shù)組中
* 將每位數(shù)字加5岭参,取余10
* 打印在控制臺
* */
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個8位數(shù)以下的數(shù)");
int num = sc.nextInt(); //從鍵盤獲取
//存到數(shù)組中反惕,先定義一個數(shù)組
int [] arr = new int[8];//8位及以下,所以寫8
int index = 0;//不知道輸入了幾位數(shù)演侯,所以自己定義一個索引
//將從鍵盤獲取的數(shù)據(jù)一位一位存到數(shù)組中
while (num > 0){ //假設(shè)num12345,num = 1234,num = 123,num = 12,num = 1,num = 0,不符合循環(huán)條件
arr[index] = num%10; //arr[0] = 5,arr[1] = 4,arr[2] = 3,arr[3] =2,arr[4] = 1
num/=10;//num = 1234,num = 123,num = 12,num = 1,num = 0
index++;//index = 1,index = 2,index = 3,index = 4,index =5,index為索引表示數(shù)組長度為5
}
//while循環(huán)中姿染,不僅將數(shù)據(jù)寫入到數(shù)組中,并且完成了倒序
//將每位加5秒际,取余10
for (int i = 0; i < index; i++) {
arr[i] += 5;
arr[i] %= 10;
}
//打印
for (int i = 0; i < index; i++) { //index為索引悬赏,及數(shù)組長度
System.out.print(arr[i]+" ");
}
}
}
Java中參數(shù)傳遞的問題
-基本類型:形式參數(shù)的改變對實際參數(shù)沒有影響,基本數(shù)據(jù)類型實參給方法形參傳遞的是數(shù)據(jù)值
-引用類型:形式參數(shù)的改變直接影響實際參數(shù)娄徊,引用數(shù)據(jù)類型實參給方法形參傳遞的是地址值
//看程序?qū)懡Y(jié)果
class ArgsDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a:"+a+",b:"+b); //a:10,b:20
change(a,b);
System.out.println("a:"+a+",b:"+b); //a:10,b:20
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println(arr[1]); //4
}
public static void change(int a,int b) { //a=10,b=20
System.out.println("a:"+a+",b:"+b); //a:10,b:20
a = b; //a=20
b = a + b; //b=40
System.out.println("a:"+a+",b:"+b); //a:20,b:40
}
public static void change(int[] arr) { //arr={1,2,3,4,5};
for(int x=0; x<arr.length; x++) {
if(arr[x]%2==0) {
arr[x]*=2;
}
}
//arr={1,4,3,8,5};
}
}
Day6
面向?qū)ο?/strong>
面向?qū)ο笏枷敫攀?br>
面向?qū)ο笫腔诿嫦蜻^程的編程思想
面向?qū)ο笏枷胩攸c
-是一種更符合我們思想習(xí)慣的思想
-可以將復(fù)雜的事情簡單化
-將我們從執(zhí)行者變成了指揮者
在用面向?qū)ο笏枷塍w現(xiàn)的時候闽颇,給出一個三句話使用規(guī)則,讓我們更符合面向?qū)ο笏枷?br>
-首先分析有那些類
-接著分析每個類應(yīng)該有什么
-最后分析類與類的關(guān)系
面向?qū)ο箝_發(fā)
就是不斷的創(chuàng)建對象寄锐,使用對象兵多,指揮對象做事情
面向?qū)ο笤O(shè)計
其實就是在管理和維護對象之間的關(guān)系
面向?qū)ο筇卣?br>
-封裝(encapsulation)
-繼承(inheritance)
-多態(tài)(polymorphism)
如何表示一個現(xiàn)實世界事物呢:
-屬性 就是該事物的描述信息
-行為 就是該事物能夠做什么
類:是一組相關(guān)的屬性和行為的集合
對象:是該類事物的具體體現(xiàn)
現(xiàn)實世界的事物
屬性 人的身高,體重等
行為 人可以學(xué)習(xí)橄仆,吃飯等
Java中用class描述事物也是如此
成員變量 就是事物的屬性
成員方法 就是事物的行為
定義類其實就是定義類的成員(成員變量和成員方法)
成員變量 和以前定義變量是一樣的剩膘,只不過位置發(fā)生了改變,在類中盆顾,方法外
成員方法 和以前定義方法是一樣的怠褐,只不過把static去掉
定義一個類
如何定義
按照事物到類的過程一步步分析
/*
手機事物:
屬性:品牌,價格您宪,顏色...
行為:打電話惫搏,發(fā)短信,玩游戲...
手機類:
成員變量:品牌蚕涤,價格,顏色
成員方法:打電話铣猩,發(fā)短信揖铜,玩游戲
*/
class Phone {
//品牌
String brand;
//價格
int price;
//顏色
String color;
//打電話的方法
public void call(String name) {
System.out.println("給"+name+"打電話");
}
//發(fā)短信的方法
public void sendMessage() {
System.out.println("群發(fā)短信");
}
//玩游戲的方法
public void playGame() {
System.out.println("玩游戲");
}
}
類的調(diào)用
創(chuàng)建對象:
格式:類名 對象名 = new 類名();
使用:
-對象名.成員變量
-對象名.成員方法
/*
手機類的測試
*/
class Phone {
//品牌
String brand;
//價格
int price;
//顏色
String color;
//打電話的方法
public void call(String name) {
System.out.println("給"+name+"打電話");
}
//發(fā)短信的方法
public void sendMessage() {
System.out.println("群發(fā)短信");
}
//玩游戲的方法
public void playGame() {
System.out.println("玩游戲");
}
}
class PhoneDemo {
public static void main(String[] args) {
//創(chuàng)建手機對象
//類名 對象名 = new 類名();
Phone p = new Phone();
//直接輸出成員變量值
System.out.println(p.brand+"---"+p.price+"---"+p.color);
//給成員變量賦值
p.brand = "諾基亞";
p.price = 100;
p.color = "灰色";
//再次輸出
System.out.println(p.brand+"---"+p.price+"---"+p.color);
//調(diào)用方法
p.call("張三");
p.sendMessage();
p.playGame();
}
}
對象的內(nèi)存圖
學(xué)生類
/*
在一個java文件中寫兩個類:一個基本的類,一個測試類
注意:文件名稱和測試類名稱一致
如何使用呢?
創(chuàng)建對象使用
如何創(chuàng)建對象
格式:類名 對象名 = new 類名();
如何使用成員變量
對象名.變量名
如何使用成員方法
對象名.方法名(...)
*/
//這是學(xué)生類
class Student {
//姓名
String name; //默認值null
//年齡
int age; //默認值0
//地址
String address; //默認值null
//學(xué)習(xí)
public void study() {
System.out.println("學(xué)生愛學(xué)習(xí)");
}
//吃飯
public void eat() {
System.out.println("學(xué)習(xí)餓了达皿,要吃飯");
}
//睡覺
public void sleep() {
System.out.println("學(xué)習(xí)累了天吓,要睡覺");
}
}
//這是學(xué)生測試類
class StudentDemo {
public static void main(String[] args) {
//類名 對象名 = new 類名();
Student s = new Student();
//輸出成員變量值
//System.out.println(s.name);
//System.out.println(s.age);
//System.out.println(s.address);
//改進寫法
System.out.println(s.name+"---"+s.age+"---"+s.address);
//給成員變量賦值
s.name = "張三";
s.age = 18;
s.address = "北京";
//賦值后的輸出
System.out.println(s.name+"---"+s.age+"---"+s.address);
//調(diào)用方法
s.study();
s.eat();
s.sleep();
}
}
Day7
成員變量和局部變量的區(qū)別
在類中的位置不同
-成員變量:在類中方法外
-局部變量:在方法定義中或者方法聲明上
在內(nèi)存中的位置不同
-成員變量:在堆內(nèi)存
-局部變量:在棧內(nèi)存
生命周期不同
-成員變量:隨著對象的創(chuàng)建而存在贿肩,隨著對象的消失而消失
-局部變量:隨著方法的調(diào)用而存在,隨著方法的調(diào)用完畢而消失
初始化值不同
-成員變量:有默認初始化值
-局部變量:沒有默認初始化值龄寞,必須定義汰规,賦值,然后才能使用
注意事項:
局部變量名稱可以和成員變量名稱一樣物邑,在方法中使用的時候溜哮,采用的是就近原則
匿名對象
就是沒有名字的對象
匿名對象的應(yīng)用場景:
調(diào)用方法,僅僅只調(diào)用一次的時候
注意:調(diào)用多次的時候色解,不適合
好處:匿名對象調(diào)用完畢就是垃圾茂嗓。可以被垃圾回收器回收
匿名對象可以作為實際參數(shù)傳遞
private關(guān)鍵字
是一個權(quán)限修飾符
可以修飾成員變量和成員方法
被其修飾的成員只能在本類中被訪問
封裝:是指隱藏對象的屬性和實現(xiàn)細節(jié)科阎,僅對外提供公共訪問方式述吸。
class Demo {
//用private修飾
private int num = 10;
public void show() {
System.out.println(num);
}
private void method() {
System.out.println("method");
}
public void function() {
method();
}
}
class PrivateDemo {
public static void main(String[] args) {
Demo d = new Demo();
//不能訪問私有的成員變量
//System.out.println(d.num);
d.show();
//不能訪問私有的成員方法
//d.method();
d.function();
}
}
對數(shù)據(jù)進行限制
class Student {
//姓名
String name;
//年齡
private int age; //對年齡進行限制
//寫一個方法對數(shù)據(jù)進行限制
public void setAge(int a) {
if(a < 0 || a > 120) {
System.out.println("你給的年齡有問題");
}else {
age = a;
}
}
//show()方法,顯示所有成員變量值
public void show() {
System.out.println("姓名:"+name);
System.out.println("年齡:"+age);
}
}
class StudentDemo { //測試類
public static void main(String[] args) {
//創(chuàng)建學(xué)生對象
Student s = new Student();
s.show();
System.out.println("--------------");
//給成員變量賦值
s.name = "張三";
//s.age = 27; //私有,不可訪問
s.setAge(27);
s.show();
System.out.println("--------------");
//給age賦值
//s.age = -27; //這個數(shù)據(jù)是不合理的
//通過方法給值
s.setAge(-27);
s.show();
System.out.println("--------------");
}
}
封裝private最常見的應(yīng)用
-把成員變量用private修飾
-提供對應(yīng)的getXxx()/setXxx()方法 set賦值锣笨,用來輸入蝌矛,get獲取值,用來輸出
class Student {
//姓名
private String name;
//年齡
private int age;
//姓名獲取值
public String getName() {
return name;
}
//姓名設(shè)置值
public void setName(String n) {
name = n;
}
//年齡獲取值
public int getAge() {
return age;
}
//年齡賦值
public void setAge(int a) {
age = a;
}
}
//測試類
class StudentTest {
public static void main(String[] args) {
//創(chuàng)建學(xué)生對象
Student s = new Student();
//使用成員變量
//錯誤:被私有修飾了错英,外界不能直接訪問了
//System.out.println(s.name+"---"+s.age);
System.out.println(s.getName()+"---"+s.getAge());
//給成員變量賦值
//s.name = "張三";
//s.age = 27;
//通過方法給賦值
s.setName("張三");
s.setAge(27);
System.out.println(s.getName()+"---"+s.getAge());
}
}
this關(guān)鍵字
this:是當(dāng)前類的對象引用入撒,簡單的記,它就代表當(dāng)前類的一個對象
注意:誰調(diào)用這個方法走趋,在該方法內(nèi)部的this就代表誰衅金。
this的場景:
解決局部變量隱藏成員變量
class Student {
//姓名
private String name;
//年齡
private int age;
//姓名獲取值
public String getName() {
return name;
}
//姓名設(shè)置值,起名字要做到見名知意
public void setName(String name) { //name = "張三";
//name = name; //變量的使用規(guī)則:就近原則
//這里是類名,目前還沒有說過類似的用法簿煌,所以這個是有問題的
//這里的調(diào)用只能通過對象名
//這個對象如果存在氮唯,它應(yīng)該代表的是Student的一個對象
//那么,誰能夠代表當(dāng)前類的對象呢? java就提供了一個關(guān)鍵字 this
//Student.name = name;
this.name = name;
}
//年齡獲取值
public int getAge() {
return age;
}
//年齡賦值
public void setAge(int age) {
this.age = age;
}
}
//測試類
class StudentTest {
public static void main(String[] args) {
//創(chuàng)建學(xué)生對象
Student s = new Student();
//給成員變量賦值
s.setName("張三");
s.setAge(27);
//獲取數(shù)據(jù)
System.out.println(s.getName()+"---"+s.getAge());
}
}
/*
標準的代碼改進版
this:哪個對象調(diào)用那個方法姨伟,this就代表那個對象
*/
class Student {
private String name;
private int age;
public String getName() {
return name; //這里其實是隱含了this
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class StudentTest2 {
public static void main(String[] args) {
//創(chuàng)建一個對象
Student s1 = new Student();
s1.setName("張三");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
//創(chuàng)建第二個對象
Student s2 = new Student();
s2.setName("李四");
s2.setAge(30);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}
構(gòu)造方法
構(gòu)造方法作用概述
給對象的數(shù)據(jù)進行初始化
構(gòu)造方法格式
方法名與類名相同
沒有返回值類型惩琉,連void都沒有
沒有具體的返回值
class Student {
private String name; //null
private int age; //0
public Student() { //創(chuàng)建了一個構(gòu)造方法
System.out.println("這是構(gòu)造方法");
}
}
class ConstructDemo {
public static void main(String[] args) {
//創(chuàng)建對象
Student s = new Student();
System.out.println(s); //輸出這是構(gòu)造方法跟地址值,說明經(jīng)過了上邊的public Student
}
}
構(gòu)造方法注意事項
如果你不提供構(gòu)造方法夺荒,系統(tǒng)會給出默認構(gòu)造方法
如果你提供了構(gòu)造方法瞒渠,系統(tǒng)將不再提供
構(gòu)造方法也是可以重載的
構(gòu)造方法賦值的形式
public class People {
//姓名
String name;
//年齡
int age;
//住址
String address;
//構(gòu)造方法無參
public People(){ }
//有參
public People(String name,int age){
this.name = name;
this.age = age;
}
//三個參數(shù)
public People(String name,int age,String address){
this.age = age;
this.name = name;
this.address = address;
}
//show打印所有信息
public void show(){
System.out.println("姓名:"+name+" 年齡:"+age+" 住址:"+address);
}
}
class PeopleText{
public static void main(String[] args) {
//創(chuàng)建對象無參
People p = new People();
p.name = "張三";
p.age = 18;
p.address = "山東省";
p.show();
//兩個參數(shù)的
People p1 = new People("李四",15);
p1.address = "北京省";
p1.show();
//三個參數(shù)的
People p2 = new People("王五",15,"山東省");
p2.show();
}
}
給成員變量賦值有兩種方式:
-setXxx()
-構(gòu)造方法
成員方法
根據(jù)返回值:
-void類型
-非void類型
形式參數(shù):
-空參方法
-非空參方法
四種方式的調(diào)用:
class Student {
public String getString() {
return "helloworld";
}
public void show() {
System.out.println("show");
}
public void method(String name) {
System.out.println(name);
}
public String function(String s1,String s2) {
return s1+s2;
}
}
class StudentDemo {
public static void main(String[] args) {
//創(chuàng)建對象
Student s = new Student();
//調(diào)用無參無返回值方法
s.show();
//調(diào)用無參有返回值方法
String result = s.getString();
System.out.println(result);
//調(diào)用帶參無返回值的方法
s.method("張三");
//調(diào)用帶參帶返回值的方法
String result2 = s.function("hello","world");
System.out.println(result2);
}
}
類分為成員變量,構(gòu)造方法,成員方法
成員變量
構(gòu)造方法
-無參構(gòu)造方法
-帶參構(gòu)造方法
成員方法
-getXxx()
-setXxx()
類的標準寫法
/*
學(xué)生類:
成員變量:
name,age
構(gòu)造方法:
無參技扼,帶兩個參
成員方法:
getXxx()/setXxx()
show():輸出該類的所有成員變量值
給成員變量賦值:
A:setXxx()方法
B:構(gòu)造方法
輸出成員變量值的方式:
A:通過getXxx()分別獲取然后拼接
B:通過調(diào)用show()方法搞定
*/
class Student {
//姓名
private String name;
//年齡
private int age;
//構(gòu)造方法
public Student() {
}
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//輸出所有的成員變量值
public void show() {
System.out.println(name+"---"+age);
}
}
//測試類
class StudentTest {
public static void main(String[] args) {
//方式1給成員變量賦值
//無參構(gòu)造+setXxx()
Student s1 = new Student();
s1.setName("張三");
s1.setAge(27);
//輸出值
System.out.println(s1.getName()+"---"+s1.getAge());
s1.show();
System.out.println("----------------------------");
//方式2給成員變量賦值
Student s2 = new Student("李四",30);
System.out.println(s2.getName()+"---"+s2.getAge());
s2.show();
}
}
注意:
-給成員變量賦值有兩種方式伍玖,可以只寫一種,推薦使用setXxx()方法,單個輸入更靈活
-如果不單獨獲取數(shù)據(jù),可以不寫getXxx()方法
類的初始化過程
Student s = new Student();在內(nèi)存中做了哪些事情
-加載Student.class文件進內(nèi)存
-在棧內(nèi)存為s開辟空間
-在堆內(nèi)存為學(xué)生對象開辟空間
-對學(xué)生對象的成員變量進行默認初始化
-對學(xué)生對象的成員變量進行顯示初始化
-通過構(gòu)造方法對學(xué)生對象的成員變量賦值
-學(xué)生對象初始化完畢剿吻,把對象地址賦值給s變量
static關(guān)鍵字
可以修飾成員變量和成員方法
static關(guān)鍵字特點
-隨著類的加載而加載
-優(yōu)先于對象存在
-被類的所有對象共享(這也是我們判斷是否使用靜態(tài)關(guān)鍵字的條件)
-可以通過類名調(diào)用
可以通過類名和對象名調(diào)用
class Student {
//非靜態(tài)變量
int num = 10;
//靜態(tài)變量
static int num2 = 20;
}
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.num);
System.out.println(Student.num2); //可以通過類名調(diào)用
System.out.println(s.num2); //可以通過對象調(diào)用
}
}
/*
定義一個人類
姓名和年齡都是變化的窍箍,因為每個人的姓名和年齡是不同的。
但是,我們想到的都是中國人椰棘,他們的國籍是一樣的纺棺。
一樣的國籍,我每次創(chuàng)建對象邪狞,在堆內(nèi)存都要開辟這樣的空間祷蝌,很浪費
針對多個對象有共同的這樣的成員變量值的時候,
Java就提高了一個關(guān)鍵字來修飾:static帆卓。
*/
class Person {
//姓名
String name;
//年齡
int age;
//國籍
static String country; //靜態(tài)修飾
public Person(){}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person(String name,int age,String country) {
this.name = name;
this.age = age;
this.country = country;
}
public void show() {
System.out.println("姓名:"+name+",年齡:"+age+",國籍:"+country);
}
}
class PersonDemo {
public static void main(String[] args) {
//創(chuàng)建對象1
Person p1 = new Person("鄧麗君",16,"中國");
p1.show();//輸出姓名:鄧麗君,年齡16,國籍中國
//創(chuàng)建對象2
Person p2 = new Person("楊冪",22); //因為country是靜態(tài)static修飾的,相當(dāng)于默認值,所以這個不賦值也是中國
p2.show();//輸出姓名:楊冪,年齡22,國籍中國
//創(chuàng)建對象3
Person p3 = new Person("鳳姐",20);
p3.show(); //同上
p3.country = "美國";
p3.show();//輸出姓名:鳳姐,年齡20,國籍美國
p1.show();//輸出姓名:鄧麗君,年齡16,國籍美國
p2.show();//輸出姓名:楊冪,年齡22,國籍美國
//p1 p2的國際為什么改變,因為用的同一個靜態(tài)修飾即默認值,在內(nèi)存中用的同一塊地址,所以會改變
}
}
static關(guān)鍵字注意事項
-在靜態(tài)方法中是沒有this關(guān)鍵字的
-靜態(tài)方法只能訪問靜態(tài)的成員變量和靜態(tài)的成員方法
/*static關(guān)鍵字注意事項
在靜態(tài)方法中是沒有this關(guān)鍵字的
如何理解呢?
靜態(tài)是隨著類的加載而加載巨朦,this是隨著對象的創(chuàng)建而存在。
靜態(tài)比對象先存在鳞疲。
靜態(tài)方法只能訪問靜態(tài)的成員變量和靜態(tài)的成員方法
靜態(tài)方法:
成員變量:只能訪問靜態(tài)變量
成員方法:只能訪問靜態(tài)成員方法
非靜態(tài)方法:
成員變量:可以是靜態(tài)的罪郊,也可以是非靜態(tài)的
成員方法:可是是靜態(tài)的成員方法,也可以是非靜態(tài)的成員方法尚洽。
簡單記:
靜態(tài)只能訪問靜態(tài)悔橄。
*/
class Teacher {
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println(num); //隱含的告訴你訪問的是成員變量
System.out.println(this.num); //明確的告訴你訪問的是成員變量
System.out.println(num2);
//function();
//function2();
}
public static void method() {
//無法從靜態(tài)上下文中引用非靜態(tài) 變量 num
//System.out.println(num);
System.out.println(num2);
//無法從靜態(tài)上下文中引用非靜態(tài) 方法 function()
//function();
function2();
}
public void function() {
}
public static void function2() {
}
}
class TeacherDemo {
public static void main(String[] args) {
//創(chuàng)建對象
Teacher t = new Teacher();
t.show();
System.out.println("------------");
t.method();
}
}
靜態(tài)變量和成員變量的區(qū)別
所屬不同
-靜態(tài)變量屬于類,所以也稱為為類變量
-成員變量屬于對象腺毫,所以也稱為實例變量(對象變量)
內(nèi)存中位置不同
-靜態(tài)變量存儲于方法區(qū)的靜態(tài)區(qū)
-成員變量存儲于堆內(nèi)存
內(nèi)存出現(xiàn)時間不同
-靜態(tài)變量隨著類的加載而加載癣疟,隨著類的消失而消失
-成員變量隨著對象的創(chuàng)建而存在,隨著對象的消失而消失
調(diào)用不同
-靜態(tài)變量可以通過類名調(diào)用潮酒,也可以通過對象調(diào)用
-成員變量只能通過對象名調(diào)用
main方法詳解
main方法的格式講解:
public static void main(String[] args) {...}
public:公共的睛挚,訪問權(quán)限是最大的。由于main方法是被jvm調(diào)用急黎,所以權(quán)限要夠大
static:靜態(tài)的扎狱,不需要創(chuàng)建對象,通過類名就可以,方便jvm的調(diào)用
void:因為我們曾經(jīng)說過勃教,方法的返回值是返回給調(diào)用者淤击,而main方法是被jvm調(diào)用,你返回內(nèi)容給jvm沒有意義
main:是一個常見的方法入口。我見過的語言都是以main作為入口
String[] args:這是一個字符串?dāng)?shù)組,這個東西早期是為了接收鍵盤錄入的數(shù)據(jù)的
格式是:java MainDemo hello world java
Day8
制作一個代碼說明書
/*
我想要對數(shù)組進行操作
如何制作一個說明書呢
寫一個工具類
對這個類加入文檔注釋
怎么加
加些什么東西
用工具解析文檔注釋
javadoc工具
格式
javadoc -d 目錄 -author -version ArrayTool.java
目錄:就可以寫一個文件夾的路徑
制作幫助文檔出錯:
找不到可以文檔化的公共或受保護的類:告訴我們類的權(quán)限不夠
*/
class ArrayDemo {
public static void main(String[] args) {
//定義數(shù)組
int[] arr = {28,55,37,46,19};
//遍歷
ArrayTool.printArray(arr);
//獲取最值
int max = ArrayTool.getMax(arr);
System.out.println("max:"+max);
//獲取55的索引值
int index = ArrayTool.getIndex(arr,55);
System.out.println("index:"+index);
}
}
/**
* 這是針對數(shù)組進行操作的工具類
* @author 張三
* @version V1.0
*/
public class ArrayTool {
//把構(gòu)造方法私有故源,外界就不能在創(chuàng)建對象了
/**
* 這是私有構(gòu)造
*/
private ArrayTool(){}
/**
* 這是遍歷數(shù)組的方法污抬,遍歷后的格式是:[元素1, 元素2, 元素3, ...]
* @param arr 這是要被遍歷的數(shù)組
*/
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
/**
* 這是獲取數(shù)組中最大值的方法
* @param arr 這是要獲取最大值的數(shù)組
* @return 返回數(shù)組中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for(int x=1; x<arr.length; x++) {
if(arr[x] > max) {
max = arr[x];
}
}
return max;
}
/**
* 獲取指定元素在數(shù)組中第一次出現(xiàn)的索引,如果元素不存在绳军,就返回-1
* @param arr 被查找的數(shù)組
* @param value 要查找的元素
* @return 返回元素在數(shù)組中的索引印机,如果不存在,返回-1
*/
public static int getIndex(int[] arr,int value) {
int index = -1;
for(int x=0; x<arr.length; x++) {
if(arr[x] == value) {
index = x;
break;
}
}
return index;
}
}
上列代碼生成的說明書
如何使用JDK的幫助文檔
1:打開幫助文檔
2:點擊顯示门驾,找到索引哎迄,看到輸入框
3:知道你要找誰?以Scanner舉例
4:在輸入框里面輸入Scanner憔涉,然后回車
5:看包
java.lang包下的類不需要導(dǎo)入堰燎,其他的全部需要導(dǎo)入会放。
要導(dǎo)入:java.util.Scanner
6:再簡單的看看類的解釋和說明顷蟆,別忘了看看該類的版本
7:看類的結(jié)構(gòu)
成員變量 字段摘要
構(gòu)造方法 構(gòu)造方法摘要
成員方法 方法摘要
8:學(xué)習(xí)構(gòu)造方法
有構(gòu)造方法 就創(chuàng)建對象
沒有構(gòu)造方法 成員可能都是靜態(tài)的
9:看成員方法
左邊
是否靜態(tài):如果靜態(tài),可以通過類名調(diào)用
返回值類型:人家返回什么腐魂,你就用什么接收
右邊
看方法名:方法名稱不要寫錯
參數(shù)列表:人家要什么,你就給什么逐纬;人家要幾個蛔屹,你就給幾個
Random方法
第一步先導(dǎo)包:import java.util.Random;
第二步創(chuàng)建對象:Random r = new Random(); //r 和 num 為變量名,可以改
第三步使用: int num = r.nextInt(20)+1; //20表示從0開始生成20個數(shù)據(jù)豁生,+1表示從1-20
猜數(shù)字小游戲
import java.util.Random;
import java.util.Scanner;
public class CaiNumber {
//猜數(shù)字范圍(1-20)
/*
* 分析:系統(tǒng)生成一個隨機數(shù)
* 用戶進行輸入一個數(shù)
* 進行比較
* 大了
* 小了
* 猜中了
* 不確定多少次猜中兔毒,用while,猜中就break甸箱;
* */
public static void main(String[] args) {
Random r = new Random();
System.out.println("系統(tǒng)生成隨機數(shù)");
int goodNum = r.nextInt(20)+1;
//System.out.println(goodNum);
//定義死循環(huán)進行猜數(shù)字
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("用戶輸入猜測的數(shù)");
int num = sc.nextInt();
if (num < goodNum){
System.out.println("猜小了育叁,請繼續(xù)");
}else if (num > goodNum){
System.out.println("猜大了,請繼續(xù)");
}else {
System.out.println("猜中了");
break;
}
}
}
}
代碼塊
在Java中芍殖,使用{}括起來的代碼被稱為代碼塊豪嗽,根據(jù)其位置和聲明的不同,可以分為
-局部代碼塊
-構(gòu)造代碼塊
-靜態(tài)代碼塊
-同步代碼塊(多線程講解)
局部代碼塊
在方法中出現(xiàn)豌骏;限定變量生命周期龟梦,及早釋放,提高內(nèi)存利用率
構(gòu)造代碼塊
在類中方法外出現(xiàn)窃躲;多個構(gòu)造方法方法中相同的代碼存放到一起计贰,每次調(diào)用構(gòu)造都執(zhí)行,并且在構(gòu)造方法前執(zhí)行
靜態(tài)代碼塊 在類中方法外出現(xiàn)蒂窒,加了static修飾
在類中方法外出現(xiàn)躁倒,并加上static修飾;用于給類進行初始化洒琢,在加載的時候就執(zhí)行秧秉,并且值執(zhí)行一次
靜態(tài)代碼塊,構(gòu)造代碼塊,構(gòu)造方法的順序問題
靜態(tài)代碼塊 > 構(gòu)造代碼塊 > 構(gòu)造方法
靜態(tài)代碼塊:只執(zhí)行一次
構(gòu)造代碼塊:每次調(diào)用構(gòu)造方法都執(zhí)行
/*
寫程序的執(zhí)行結(jié)果。
輸出結(jié)果:
main函數(shù)靜態(tài)方法
我是main方法
Student 靜態(tài)代碼塊
Student 構(gòu)造代碼塊
Student 構(gòu)造方法
Student 構(gòu)造代碼塊
Student 構(gòu)造方法
先調(diào)用main方法中的靜態(tài)代碼塊纬凤,在調(diào)用main方法福贞,創(chuàng)建對象s1,執(zhí)行Student類中的方法停士,先執(zhí)行靜態(tài)挖帘,在執(zhí)行構(gòu)造代碼塊,最后執(zhí)行構(gòu)造方法恋技,在創(chuàng)建對象s2拇舀,執(zhí)行Student類中的方法,靜態(tài)只執(zhí)行一次蜻底,所以只執(zhí)行構(gòu)造代碼塊和構(gòu)造方法
*/
class Student {
static {
System.out.println("Student 靜態(tài)代碼塊");
}
{
System.out.println("Student 構(gòu)造代碼塊");
}
public Student() {
System.out.println("Student 構(gòu)造方法");
}
}
class StudentDemo {
static {
System.out.println("main函數(shù)靜態(tài)方法");
}
public static void main(String[] args) {
System.out.println("我是main方法");
Student s1 = new Student(); //創(chuàng)建對象
Student s2 = new Student();
}
}
繼承
繼承概述:
把多個類中相同的內(nèi)容給提取出來定義到一個類中骄崩。
如何實現(xiàn)繼承呢?
Java提供了關(guān)鍵字:extends
格式:
class 子類名 extends 父類名 {}
好處:
-提高了代碼的復(fù)用性
-提高了代碼的維護性
-讓類與類之間產(chǎn)生了關(guān)系,是多態(tài)的前提
類與類產(chǎn)生了關(guān)系,其實也是繼承的一個弊端:
類的耦合性增強了要拂。
開發(fā)的原則:低耦合抠璃,高內(nèi)聚。
耦合:類與類的關(guān)系
內(nèi)聚:就是自己完成某件事情的能力
//使用繼承前
class Student {
public void eat() {
System.out.println("吃飯");
}
public void sleep() {
System.out.println("睡覺");
}
}
class Teacher {
public void eat() {
System.out.println("吃飯");
}
public void sleep() {
System.out.println("睡覺");
}
}
//使用繼承后
class Person {
public void eat() {
System.out.println("吃飯");
}
public void sleep() {
System.out.println("睡覺");
}
}
class Student extends Person {} //繼承格式
class Teacher extends Person {}
class ExtendsDemo {
public static void main(String[] args) {
Student s = new Student();
s.eat();
s.sleep();
System.out.println("-------------");
Teacher t = new Teacher();
t.eat();
t.sleep();
}
}
Java繼承的特點
-Java只支持單繼承脱惰,不支持多繼承
-Java支持多層繼承(繼承體系)
class Father {}
class Mother {}
class Son exnteds Father {} //正確的
class Son extends Father,Mother {} // 錯誤的,不可以多繼承
*/
class GrandFather {
public void show() {
System.out.println("我是爺爺");
}
}
class Father extends GrandFather { //老子繼承爺爺?shù)? public void method(){
System.out.println("我是老子");
}
}
class Son extends Father {} //兒子繼承老子的搏嗡,構(gòu)成多層繼承
class ExtendsDemo2 {
public static void main(String[] args) {
Son s = new Son();
s.method(); //使用父親的
s.show(); //使用爺爺?shù)? }
}
Java繼承中的成員關(guān)系
成員變量
子類的成員變量名稱和父類中的成員變量名稱不一樣,通過名稱訪問
子類的成員變量名稱和父類中的成員變量名稱一樣
子類的方法訪問變量的查找順序:
-在子類方法的局部范圍找拉一,有就使用
-在子類的成員范圍找采盒,有就使用
-在父類的成員范圍找,有就使用
-找不到蔚润,就報錯
構(gòu)造方法
子類的構(gòu)造方法默認會去訪問父類的無參構(gòu)造方法
是為了子類訪問父類數(shù)據(jù)的初始化
父類中如果沒有無參構(gòu)造方法磅氨,怎么辦
-子類通過super去明確調(diào)用帶參構(gòu)造
-子類通過this調(diào)用本身的其他構(gòu)造,但是一定會有一個去訪問了父類的構(gòu)造
-讓父類提供無參構(gòu)造
成員方法
子類的成員方法和父類中的成員方法名稱不一樣嫡纠,通過名稱
子類的成員方法和父類中的成員方法名稱一樣烦租,
通過子類對象訪問一個方法的查找順序:
-在子類中找,有就使用
-在父類中找货徙,有就使用
-找不到左权,就報錯
繼承的注意事項
-子類只能繼承父類所有非私有的成員(成員方法和成員變量)
-子類不能繼承父類的構(gòu)造方法,但是可以通過super關(guān)鍵字去訪問父類構(gòu)造方法
-不要為了部分功能而去繼承
什么時候考慮用繼承
繼承其實體現(xiàn)的是一種關(guān)系:"is a"痴颊。
Person //人
Student //學(xué)生
Teacher //老師
老師是人赏迟,學(xué)生也是人,就考慮繼承
水果
蘋果 //是水果的一種
香蕉 //是水果的一種
采用假設(shè)法
如果有兩個類A蠢棱,B锌杀,只有他們符合A是B的一種,或者B是A的一種泻仙,就可以考慮使用繼承
類的組成
-成員變量:
-構(gòu)造方法:
-成員方法:
在子類方法中訪問一個變量的查找順序:
-在子類方法的局部范圍找糕再,有就使用
-在子類的成員范圍找,有就使用
-在父類的成員范圍找玉转,有就使用
-如果還找不到突想,就報錯
super關(guān)鍵字
代表父類存儲空間的標識(可以理解為父類引用,可以操作父類的成員)
this 代表本類對應(yīng)的引用
用法:
調(diào)用成員變量
this.成員變量 調(diào)用本類的成員變量
super.成員變量 調(diào)用父類的成員變量
調(diào)用構(gòu)造方法
this(...) 調(diào)用本類的構(gòu)造方法
super(...) 調(diào)用父類的構(gòu)造方法
調(diào)用成員方法
this.成員方法 調(diào)用本類的成員方法
super.成員方法 調(diào)用父類的成員方法
繼承中構(gòu)造方法的關(guān)系
子類中所有的構(gòu)造方法默認都會訪問父類中空參數(shù)的構(gòu)造方法
因為子類會繼承父類中的數(shù)據(jù),可能還會使用父類的數(shù)據(jù)究抓,所以猾担,子類初始化之前,一定要先完成父類數(shù)據(jù)的初始化
注意:子類每一個構(gòu)造方法的第一條語句默認都是:super();
class Father {
int age;
public Father() {
System.out.println("Father的無參構(gòu)造方法");
}
public Father(String name) {
System.out.println("Father的帶參構(gòu)造方法");
}
}
class Son extends Father {
public Son() {
//super();
System.out.println("Son的無參構(gòu)造方法");
}
public Son(String name) {
//super();
System.out.println("Son的帶參構(gòu)造方法");
}
}
class ExtendsDemo6 {
public static void main(String[] args) {
//創(chuàng)建對象
Son s = new Son();
System.out.println("------------");
Son s2 = new Son("張三"); //不管子類是有參還是無參刺下,都走父類的無參構(gòu)造
}
}
//運行結(jié)果
Father的無參構(gòu)造方法
Son的無參構(gòu)造方法
------------
Father的無參構(gòu)造方法
Son的帶參構(gòu)造方法
如果父類沒有無參構(gòu)造方法绑嘹,那么子類的構(gòu)造方法會報錯
如何解決
-在父類中加一個無參構(gòu)造方法
-通過使用super關(guān)鍵字去顯示的調(diào)用父類的帶參構(gòu)造方法
-子類通過this去調(diào)用本類的其他構(gòu)造方法
子類中一定要有一個去訪問了父類的構(gòu)造方法,否則父類數(shù)據(jù)就沒有初始化
注意事項:
this(...)或者super(...)必須出現(xiàn)在第一條語句上
如果不是放在第一條語句上橘茉,就可能對父類的數(shù)據(jù)進行了多次初始化工腋,所以必須放在第一條語句上
class Father {
/*
public Father() {
System.out.println("Father的無參構(gòu)造方法");
}
*/
public Father(String name) {
System.out.println("Father的帶參構(gòu)造方法");
}
}
class Son extends Father {
public Son() {
super("隨便給");
System.out.println("Son的無參構(gòu)造方法");
//super("隨便給");
}
public Son(String name) {
//super("隨便給");
this();
System.out.println("Son的帶參構(gòu)造方法");
}
}
class ExtendsDemo7 {
public static void main(String[] args) {
Son s = new Son();
System.out.println("----------------");
Son ss = new Son("張三");
}
}
//結(jié)果
Father的帶參構(gòu)造方法
Son的無參構(gòu)造方法
----------------
Father的帶參構(gòu)造方法
Son的無參構(gòu)造方法
Son的帶參構(gòu)造方法
方法重寫
方法重寫:子類中出現(xiàn)了和父類中方法聲明一模一樣的方法
方法重載:本類中出現(xiàn)的方法名一樣姨丈,參數(shù)列表不同的方法,與返回值無關(guān)
子類對象調(diào)用方法的時候:先找子類本身擅腰,再找父類
方法重寫的應(yīng)用:
當(dāng)子類需要父類的功能蟋恬,而功能主體子類有自己特有內(nèi)容時,可以重寫父類中的方法惕鼓,這樣筋现,即沿襲了父類的功能,又定義了子類特有的內(nèi)容
/*
手機都有通話功能
新手機通話完成后會顯示通話時間
*/
class Phone {
public void call(String name) {
System.out.println("給"+name+"打電話");
}
}
class NewPhone extends Phone {
public void call(String name) {
//System.out.println("給"+name+"打電話");
super.call(name); //調(diào)用父類中的方法
System.out.println("通話時長");
}
}
class ExtendsDemo9 {
public static void main(String[] args) {
NewPhone np = new NewPhone();
np.call("張三"); //結(jié)果:給張三打電話箱歧,通話時長
}
}
方法重寫的注意事項
-父類中私有方法不能被重寫
因為父類私有方法子類根本就無法繼承
-子類重寫父類方法時,訪問權(quán)限不能更低
最好就一致
-父類靜態(tài)方法一膨,子類也必須通過靜態(tài)方法進行重寫
子類重寫父類方法的時候呀邢,最好聲明一模一樣
練習(xí)
1:方法重寫和方法重載的區(qū)別?方法重載能改變返回值類型嗎?
方法重寫:
在子類中,出現(xiàn)和父類中一模一樣的方法聲明的現(xiàn)象豹绪。
方法重載:
同一個類中价淌,出現(xiàn)的方法名相同,參數(shù)列表不同的現(xiàn)象瞒津。
方法重載能改變返回值類型蝉衣,因為它和返回值類型無關(guān)。
Override:方法重寫
Overload:方法重載
2:this關(guān)鍵字和super關(guān)鍵字分別代表什么?以及他們各自的使用場景和作用巷蚪。
this:代表當(dāng)前類的對象引用
super:代表父類存儲空間的標識病毡。(可以理解為父類的引用,通過這個東西可以訪問父類的成員)
場景:
成員變量:
this.成員變量
super.成員變量
構(gòu)造方法:
this(...)
super(...)
成員方法:
this.成員方法
super.成員方法
繼承版貓狗案例
/*
* 貓狗案例
* 分析:
* 貓類:
* 成員變量:
* 姓名屁柏,年齡啦膜,顏色
* 構(gòu)造方法:
* 有參跟無參
* 成員方法:
* 吃飯,睡覺淌喻,捉老鼠(貓?zhí)赜校?* 狗類:
* 成員變量:
* 姓名僧家,年齡,顏色
* 構(gòu)造方法:
* 有參跟無參
* 成員方法:
* 吃飯裸删,睡覺八拱,看門(狗特有)
*
* 把公共部門定義成一個類
* 動物類:
* 成員變量:
* 姓名,年齡涯塔,顏色
* 構(gòu)造方法:
* 有參跟無參
* 成員方法:
* 吃飯肌稻,睡覺
* */
class Animal {
//姓名
private String name;
// 年齡
private int age;
// 顏色
private String color;
//構(gòu)造方法
public Animal() {
} //無參
public Animal(String name, int age, String color) { //有參
this.name = name;
this.age = age;
this.color = color;
}
//成員方法:get,sat,吃飯,睡覺
//姓名
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//年齡
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//顏色
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//吃飯
public void eat() {
System.out.println(name + "吃飯");
}
//睡覺
public void sleep() {
System.out.println(name + "睡覺");
}
}
//貓類
class Cat extends Animal{
//無參構(gòu)造
public Cat(){}
//有參構(gòu)造
public Cat(String name,int age,String color){
super(name, age, color);
}
public void playGame(){
System.out.println(super.getName()+"捉老鼠"); //調(diào)用父類的成員方法伤塌,輸出姓名
}
}
//狗類
class Dog extends Animal{
//無參構(gòu)造
public Dog(){}
//有參構(gòu)造
public Dog(String name,int age,String color){
super(name, age, color);
}
public void lookDoor(){
System.out.println(super.getName()+"看門");
}
}
class Text{ //測試類
public static void main(String[] args) {
//貓無參
Cat cat = new Cat();
cat.setName("小花");
cat.setColor("花色");
cat.setAge(18);
cat.eat();
cat.playGame();
System.out.println(cat.getName()+cat.getAge()+cat.getColor());
System.out.println("----------");
//貓有參
Cat cat1 = new Cat("甜甜",15,"藍色");
cat1.playGame();
cat.sleep();
System.out.println(cat1.getName()+cat1.getAge()+cat1.getColor());
System.out.println("----------");
//狗無參
Dog dog = new Dog();
dog.setName("小黑");
dog.setAge(17);
dog.setColor("黑色");
dog.eat();
dog.lookDoor();
System.out.println(dog.getName()+dog.getAge()+dog.getColor());
System.out.println("----------");
//狗類有參
Dog dog1 = new Dog("小白",13,"白色");
dog1.eat();
dog1.lookDoor();
System.out.println(dog1.getName()+dog1.getAge()+dog1.getColor());
}
}
/*
結(jié)果:
小花吃飯
小花捉老鼠
小花18花色
----------
甜甜捉老鼠
小花睡覺
甜甜15藍色
----------
小黑吃飯
小黑看門
小黑17黑色
----------
小白吃飯
小白看門
小白13白色
*/
Day9
final關(guān)鍵字
繼承的代碼體現(xiàn)
由于繼承中方法有一個現(xiàn)象:方法重寫
所以灯萍,父類的功能,就會被子類給覆蓋掉,有些時候每聪,我們不想讓子類去覆蓋掉父類的功能旦棉,只能讓他使用,這個時候齿风,針對這種情況,Java就提供了一個關(guān)鍵字:final
final:最終的意思,常見的是它可以修飾類绑洛,方法救斑,變量
class Fu {
//public void show() { 將show改為用final修飾
public final void show {
System.out.println("這里是絕密資源,任何人都不能修改");
}
}
class Zi extends Fu {
//Zi中的show就無法覆蓋Fu中的show
public void show() {
System.out.println("這是一堆垃圾");
}
}
class ZiDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
final可以修飾類,方法,變量
特點:
final修飾類,該類不可以被繼承
final修飾方法,該方法不能被重寫
final修飾變量,該變量不能被重新賦值
final也可以修飾局部變量
基本數(shù)據(jù)類型的值不可以改變
引用數(shù)據(jù)類型的地址值不可以改變,但是該對象堆內(nèi)存的值可以改變
final修飾變量初始化時機
被final修飾的變量只能被賦值一次
在構(gòu)造方法完成前(非靜態(tài)的常量)
多態(tài)
是指同一個事物(對象),在不同時刻表現(xiàn)出來的不同的狀態(tài)真屯、
例:貓是貓脸候,貓也是動物
多態(tài)的前提:
要有繼承關(guān)系
要有方法重寫
要有父類引用指向子類對象
父類 fu = new 子類();
用代碼體現(xiàn)一下多態(tài)
class Fu{
public void show(){
System,out.println("這是父類的show");
}
}
class Zi extends Fu{ //要有繼承關(guān)系
public void show(){
System,out.println("這是子類的show"); //要有方法重寫
}
}
class DuiTai{
public static void main(String[] args){
Fu fu = new Zi(); //要有父類引用指向子類對象
}
}
多態(tài)中的成員訪問特點
成員變量
編譯看左邊,運行看左邊
構(gòu)造方法
創(chuàng)建子類對象的時候绑蔫,訪問父類的構(gòu)造方法运沦,對父類的數(shù)據(jù)進行初始化
成員方法
編譯看左邊,運行看右邊
靜態(tài)方法
編譯看左邊配深,運行看左邊
(靜態(tài)和類相關(guān)携添,算不上重寫,所以篓叶,訪問還是左邊的)
由于成員方法存在方法重寫烈掠,所以它運行看右邊
class Fu {
public int num = 100;
public void show() {
System.out.println("show Fu");
}
public static void function() { //靜態(tài)
System.out.println("function Fu");
}
}
class Zi extends Fu {
public int num = 1000;
public int num2 = 200;
public void show() {
System.out.println("show Zi");
}
public void method() {
System.out.println("method zi");
}
public static void function() { //靜態(tài)
System.out.println("function Zi");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
//要有父類引用指向子類對象。
//父 f = new 子();
Fu f = new Zi();
System.out.println(f.num); //輸出100缸托,成員變量運行看左邊
//找不到符號左敌,成員變量編譯看左邊
//System.out.println(f.num2);
f.show(); //輸出showZi,成員方法運行看右邊俐镐,因為有方法重寫
//找不到符號矫限,成員方法編譯看左邊,父類中沒有京革,所以找不到
//f.method();
f.function(); //輸出funcyion Fu奇唤,靜態(tài)方法編譯看左邊,輸出看左邊
}
}
多態(tài)的好處
提高了代碼的維護性(由繼承保證)
提高了代碼的擴展性(由多態(tài)保證)
class Animal {
public void eat(){
System.out.println("eat");
}
public void sleep(){
System.out.println("sleep");
}
}
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
public void sleep(){
System.out.println("狗站著睡覺");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚");
}
public void sleep() {
System.out.println("貓趴著睡覺");
}
}
class Pig extends Animal {
public void eat() {
System.out.println("豬吃白菜");
}
public void sleep() {
System.out.println("豬側(cè)著睡");
}
}
//針對動物操作的工具類
class AnimalTool {
private AnimalTool(){}
/*
//調(diào)用貓的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
//調(diào)用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
//調(diào)用豬的功能
public static void usePig(Pig p) {
p.eat();
p.sleep();
}
*/
public static void useAnimal(Animal a) { //因為每添加一個動物類就要改工具類匹摇,所以直接改成動物類
a.eat();
a.sleep();
}
}
class DuoTaiDemo2 {
public static void main(String[] args) {
//我喜歡貓咬扇,就養(yǎng)了一只
Cat c = new Cat();
c.eat();
c.sleep();
//我很喜歡貓,所以廊勃,又養(yǎng)了一只
Cat c2 = new Cat();
c2.eat();
c2.sleep();
//我特別喜歡貓懈贺,又養(yǎng)了一只
Cat c3 = new Cat();
c3.eat();
c3.sleep();
//...
System.out.println("--------------");
//問題來了,我養(yǎng)了很多只貓,每次創(chuàng)建對象是可以接受的
//但是呢?調(diào)用方法坡垫,你不覺得很相似嗎?僅僅是對象名不一樣梭灿。
//我們準備用方法改進
//調(diào)用方式改進版本
//useCat(c);
//useCat(c2);
//useCat(c3);
//AnimalTool.useCat(c);
//AnimalTool.useCat(c2);
//AnimalTool.useCat(c3);
AnimalTool.useAnimal(c);
AnimalTool.useAnimal(c2);
AnimalTool.useAnimal(c3);
System.out.println("--------------");
//我喜歡狗
Dog d = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
//AnimalTool.useDog(d);
//AnimalTool.useDog(d2);
//AnimalTool.useDog(d3);
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(d2);
AnimalTool.useAnimal(d3);
System.out.println("--------------");
//我喜歡寵物豬
//定義一個豬類,它要繼承自動物冰悠,提供兩個方法堡妒,并且還得在工具類中添加該類方法調(diào)用
Pig p = new Pig();
Pig p2 = new Pig();
Pig p3 = new Pig();
//AnimalTool.usePig(p);
//AnimalTool.usePig(p2);
//AnimalTool.usePig(p3);
AnimalTool.useAnimal(p);
AnimalTool.useAnimal(p2);
AnimalTool.useAnimal(p3);
System.out.println("--------------");
//我喜歡寵物狼,老虎溉卓,豹子...
//定義對應(yīng)的類皮迟,繼承自動物搬泥,提供對應(yīng)的方法重寫,并在工具類添加方法調(diào)用
//前面幾個必須寫伏尼,我是沒有意見的
//但是忿檩,工具類每次都改,麻煩不
//我就想爆阶,你能不能不改了
//太簡單:把所有的動物都寫上燥透。問題是名字是什么呢?到底哪些需要被加入呢?
//改用另一種解決方案。
}
/*
//調(diào)用貓的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
//調(diào)用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
*/
}
多態(tài)的弊端
不能使用子類特有的功能
class Fu{
public void show(){
System.out.println(show 父類);
}
}
class Zi extends Fu{
public void show(){
System.out.println(show 子類);
}
public void eat(){
System.out.println("吃飯");
}
}
class DuoTai{
public static void main(String[] args){
Fu fu = new Zi();
fu.show(); //可以執(zhí)行
fu.eat(); //不可以執(zhí)行辨图,父類不能訪問子類特有的功能
}
}
如何解決多態(tài)的弊端:
-可以新建一個子類對象調(diào)用子類特有的方法
-向下轉(zhuǎn)型
Zi z = (Zi) f; //要求該f必須能轉(zhuǎn)化成Zi的
對象間的轉(zhuǎn)型問題
向上轉(zhuǎn)型:
Fu f = new Zi();
向下轉(zhuǎn)型:
Zi z = (Zi)f; //要求該f必須是能夠轉(zhuǎn)換為Zi的
錯誤提示:ClassCastException:類型轉(zhuǎn)換異常班套,一般在多態(tài)的向下轉(zhuǎn)型中容易出現(xiàn)
多態(tài)版貓狗案例
class DongWu{ //動物類
//吃飯
public void eat(){
System.out.println("吃飯");
}
//睡覺
public void sleep(){
System.out.println("睡覺");
}
}
class Mao extends DongWu{ //定義貓類繼承動物類
//吃飯
public void eat(){
System.out.println("貓吃魚");
}
//睡覺
public void sleep(){
System.out.println("貓趴著睡覺");
}
//貓玩游戲
public void playGame(){
System.out.println("貓玩捉迷藏");
}
}
class Gou extends DongWu{ //定義狗類繼承動物類
//吃飯
public void eat(){
System.out.println("狗吃肉");
}
//睡覺
public void sleep(){
System.out.println("狗站著睡覺");
}
//看門
public void lookDoor(){
System.out.println("狗看門");
}
}
public class DuoTaiTest {
/*
* 用多態(tài)實現(xiàn)貓狗案例
* 分析:
* 多態(tài)要有繼承
* 多態(tài)要有父類指向子類對象
* 要有方法重寫
* */
public static void main(String[] args) {
//將動物定義為狗
DongWu dw = new Gou();
dw.eat();
dw.sleep();
//無法執(zhí)行dw.lookDoor
//還原為狗
Gou g = (Gou)dw;
g.lookDoor();
System.out.println("--------");
dw = new Mao();
dw.sleep();
dw.eat();
Mao m = (Mao)dw;
m.playGame();
}
}
練習(xí)
/*
看程序?qū)懡Y(jié)果:先判斷有沒有問題,如果沒有故河,寫出結(jié)果
*/
class Fu {
public void show() {
System.out.println("fu show");
}
}
class Zi extends Fu {
public void show() {
System.out.println("zi show");
}
public void method() {
System.out.println("zi method");
}
}
class DuoTaiTest3 {
public static void main(String[] args) {
Fu f = new Zi();
//找不到符號
//f.method(); //有問題孽尽,多態(tài)中成員方法編譯看左邊,父類中沒有method方法忧勿,所以報錯,找不到符號
f.show(); //可以運行瞻讽,編譯看左邊鸳吸,父類中有show方法,運行看右邊速勇,輸出右邊的子類show晌砾,子類重寫父類
}
}
多態(tài)的成員訪問特點:
方法:編譯看左邊,運行看右邊
繼承的時候:
子類中有和父類中一樣的方法烦磁,叫重寫
子類中沒有父親中出現(xiàn)過的方法养匈,方法就被繼承過來了
/*
看程序?qū)懡Y(jié)果:先判斷有沒有問題,如果沒有都伪,寫出結(jié)果
*/
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
/*
public void show() { //被繼承呕乎,相當(dāng)于有
show2();
}
*/
public void show2() {
System.out.println("愛");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show(); //打印愛
B b = new C();
b.show(); //打印你
}
}
抽象類
抽象類得聲明格式:用abstract修飾
例:abstract class Person
抽象類的概述:
動物不應(yīng)該定義為具體的東西,而且動物中的吃陨晶,睡等也不應(yīng)該是具體的猬仁,我們把一個不是具體的功能稱為抽象的功能,而一個類中如果有抽象的功能先誉,該類必須得是抽象類
抽象類的特點:
抽象類和抽象方法必須用abstract關(guān)鍵字修飾
抽象類中不一定有抽象方法,但是有抽象方法的類必須定義為抽象類
抽象類不能實例化湿刽,因為他不是具體的
抽象類有構(gòu)造方法,用于子類訪問父類數(shù)據(jù)的初始化
抽象的子類
抽象類褐耳,可以不重寫父類的抽象方法
具體類诈闺,必須重寫父類所有的抽象方法
抽象類的實例化其實是靠具體的子類實現(xiàn)的。是多態(tài)的方式
Animal a = new Cat();
//abstract class Animal //抽象類的聲明格式
abstract class Animal {
//抽象方法
//public abstract void eat(){} //空方法體,這個會報錯铃芦。抽象方法不能有主體
public abstract void eat(); //空方法體
public Animal(){}
}
//子類是抽象類
abstract class Dog extends Animal {}
//子類是具體類
class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚"); //就需要重寫父類的所有抽象方法
}
}
class AbstractDemo {
public static void main(String[] args) {
//創(chuàng)建對象
//Animal是抽象的; 無法實例化
//Animal a = new Animal();
//可以通過多態(tài)的方式實現(xiàn)抽象類的實例化
Animal a = new Cat();
a.eat();
}
}
抽象類的成員特點:
成員變量:既可以是變量雅镊,也可以是常量
構(gòu)造方法:有襟雷,用于子類訪問父類數(shù)據(jù)的初始化
成員方法:既可以是抽象的,也可以是非抽象的
抽象類的成員方法特性:
抽象方法 強制要求子類做的事情
非抽象方法 子類繼承的事情漓穿,提高代碼復(fù)用性
抽象類貓狗案例
貓狗案例
具體事物:貓嗤军,狗
共性:姓名,年齡晃危,吃飯
分析:從具體到抽象
貓:
成員變量:姓名叙赚,年齡
構(gòu)造方法:無參,帶參
成員方法:吃飯(貓吃魚)
狗:
成員變量:姓名僚饭,年齡
構(gòu)造方法:無參震叮,帶參
成員方法:吃飯(狗吃肉)
因為有共性的內(nèi)容,所以就提取了一個父類鳍鸵。動物苇瓣。
但是又由于吃飯的內(nèi)容不一樣,所以吃飯的方法是抽象的偿乖,
而方法是抽象的類击罪,類就必須定義為抽象類。
抽象動物類:
成員變量:姓名贪薪,年齡
構(gòu)造方法:無參媳禁,帶參
成員方法:吃飯();
實現(xiàn):從抽象到具體
動物類:
成員變量:姓名,年齡
構(gòu)造方法:無參画切,帶參
成員方法:吃飯();
狗類:
繼承自動物類
重寫吃飯();
貓類:
繼承自動物類
重寫吃飯();
代碼實現(xiàn)
/*
* 抽象類實現(xiàn)貓狗案例
*
* */
abstract class Animal { //創(chuàng)建抽象類動物
//姓名
private String name;
//年齡
private int age;
//構(gòu)造方法竣稽,無參,有參
public Animal(){}
public Animal(String name,int age){
this.name = name;
this.age = age;
}
//成員方法霍弹,get和sat
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
//抽象方法
abstract void eat();
}
//定義具體類貓
class Cat extends Animal{
//成員變量繼承
//構(gòu)造方法
public Cat(){}
public Cat(String name,int age){
super(name, age);
}
//成員方法
public void eat(){
System.out.println(super.getName()+"吃魚");
}
}
//定義具體類狗
class Dog extends Animal{
//成員變量繼承
//構(gòu)造方法
public Dog(){}
public Dog(String name,int age){
super(name, age);
}
//成員方法
public void eat(){
System.out.println(super.getName()+"狗吃肉");
}
}
//測試類
class ChouXiangTest{
public static void main(String[] args) {
//創(chuàng)建對象
//無參
Cat c = new Cat();
c.setName("小花");
c.setAge(3);
c.eat();
System.out.println(c.getName()+"---"+c.getAge());
//有參
Cat c2 = new Cat("小白",5);
c2.eat();
System.out.println(c2.getName()+"---"+c2.getAge());
//多態(tài)
Animal a = new Dog();
a.setName("小黑");
a.setAge(5);
a.eat();
System.out.println(a.getName()+"----"+a.getAge());
}
}
接口
特點:
接口用關(guān)鍵字interface表示
interface 接口名 {}
類實現(xiàn)接口用implements表示
class 類名 implements 接口名 {}
接口不能實例化毫别,按照多態(tài)的方式來實例化
接口的子類
可以是抽象類,但是意義不大
可以是具體類典格,要重寫接口中的所有抽象方法(推薦方案)
由此可見:
A:具體類多態(tài)(幾乎沒有)
B:抽象類多態(tài)(常用)
C:接口多態(tài)(最常用)
//定義動物培訓(xùn)接口
interface AnimalTrain {
public abstract void jump();
}
//抽象類實現(xiàn)接口
abstract class Dog implements AnimalTrain {
}
//具體類實現(xiàn)接口
class Cat implements AnimalTrain {
public void jump() {
System.out.println("貓可以跳高了");
}
}
class InterfaceDemo {
public static void main(String[] args) {
//AnimalTrain是抽象的; 無法實例化
//AnimalTrain at = new AnimalTrain();
//at.jump();
AnimalTrain at = new Cat();
at.jump(); //根據(jù)方法重寫的要求岛宦,執(zhí)行看右邊,所以輸出貓的jump钝计,貓可以跳高了
}
}
接口成員特點
成員變量:只能是常量恋博,并且是靜態(tài)的
默認修飾符:public static final //自己寫出默認修飾符
構(gòu)造方法:接口沒有構(gòu)造方法,因為接口主要是擴展功能私恬,沒有具體存在债沮,初始化靠父類Object
成員方法:只能是抽象方法
默認修飾符:public abstract //自己寫出默認修飾符
所有的類都默認繼承自一個類:Object
類 Object 是類層次結(jié)構(gòu)的根類,每個類都使用 Object 作為超類
接口名+Impl這種格式是接口的實現(xiàn)類格式
interface Inter {
public int num = 10;
public final int num2 = 20; //不寫全會默認給出
public static final int num3 = 30; //最終格式
//錯誤: 需要<標識符>
//public Inter() {} //接口沒有構(gòu)造方法
//接口方法不能帶有主體
//public void show() {} //說明是抽象的
//abstract void show(); //默認public
public void show(); //默認abstract
}
//接口名+Impl這種格式是接口的實現(xiàn)類格式
/*
class InterImpl implements Inter {
public InterImpl() {
super();
}
}
*/
class InterImpl extends Object implements Inter { //繼承自O(shè)bject
public InterImpl() {
super();
}
public void show() {}
}
//測試類
class InterfaceDemo2 {
public static void main(String[] args) {
//創(chuàng)建對象
Inter i = new InterImpl();
System.out.println(i.num);
System.out.println(i.num2);
//i.num = 100;
//i.num2 = 200;
//System.out.println(i.num); //無法為最終變量num分配值,說明是final修飾
//System.out.println(i.num2);//無法為最終變量num2分配值
System.out.println(Inter.num);
System.out.println(Inter.num2);
System.out.println("--------------");
}
}
接口成員特點
成員變量;只能是常量本鸣,并且是靜態(tài)的
默認修飾符:public static final 自己手動給出
構(gòu)造方法:接口沒有構(gòu)造方法
成員方法:只能是抽象方法
默認修飾符:public abstract 自己手動給出
所有的類都默認繼承自一個類:Object
類 Object 是類層次結(jié)構(gòu)的根類疫衩。每個類都使用 Object 作為超類
接口名+Impl這種格式是接口的實現(xiàn)類格式
interface Inter {
public int num = 10;
public final int num2 = 20; //沒寫的默認給出
public static final int num3 = 30; //最終格式
//錯誤: 需要<標識符> 沒有構(gòu)造方法
//public Inter() {}
//接口方法不能帶有主體
//public void show() {}
//abstract void show(); //默認public
public void show(); //默認abstract
}
//接口名+Impl這種格式是接口的實現(xiàn)類格式
/*
class InterImpl implements Inter {
public InterImpl() {
super();
}
}
*/
class InterImpl extends Object implements Inter { //默認繼承自O(shè)bject類
public InterImpl() {
super();
}
public void show() {}
}
//測試類
class InterfaceDemo2 {
public static void main(String[] args) {
//創(chuàng)建對象
Inter i = new InterImpl();
System.out.println(i.num);
System.out.println(i.num2);
//i.num = 100;
//i.num2 = 200;
//System.out.println(i.num); //無法為最終變量num分配值是final修飾默認
//System.out.println(i.num2);//無法為最終變量num2分配值
System.out.println(Inter.num);
System.out.println(Inter.num2);
System.out.println("--------------");
}
}
類,接口之間的關(guān)系
類與類:
繼承關(guān)系,只能單繼承,可以多層繼承
類與接口:
實現(xiàn)關(guān)系,可以單實現(xiàn),也可以多實現(xiàn)荣德,并且還可以在繼承一個類的同時實現(xiàn)多個接口
接口與接口:
繼承關(guān)系,可以單繼承,也可以多繼承
一個類實現(xiàn)多繼承接口時闷煤,要重寫接口多繼承中的所有方法
interface Father {
public abstract void show();
}
interface Mother {
public abstract void show2();
}
interface Sister extends Father,Mother { //接口可以多繼承
}
//class Son implements Father,Mother //多實現(xiàn)
class Son extends Object implements Father,Mother {
public void show() {
System.out.println("show son");
}
public void show2() {
System.out.println("show2 son");
}
}
class InterfaceDemo3 {
public static void main(String[] args) {
//創(chuàng)建對象
Father f = new Son();
f.show();
//f.show2(); //報錯,方法看左邊童芹,左邊沒有show2
Mother m = new Son();
//m.show(); //報錯,方法看左邊,左邊沒有show
m.show2();
}
}
抽象類和接口的區(qū)別
成員區(qū)別
抽象類:
成員變量:可以變量鲤拿,也可以常量
構(gòu)造方法:有
成員方法:可以抽象假褪,也可以非抽象
接口:
成員變量:只可以常量
構(gòu)造方法:沒有
成員方法:只可以抽象
關(guān)系區(qū)別
類與類
繼承,單繼承
類與接口
實現(xiàn)近顷,單實現(xiàn)生音,多實現(xiàn)
接口與接口
繼承,單繼承窒升,多繼承
設(shè)計理念區(qū)別
抽象類 被繼承體現(xiàn)的是:”is a”的關(guān)系缀遍,抽象類中定義的是該繼承體系的共性功能
接口 被實現(xiàn)體現(xiàn)的是:”like a”的關(guān)系,接口中定義的是該繼承體系的擴展功能(特有功能)
接口版貓狗案例
/*
* 需求:利用接口實現(xiàn)貓狗案例跳高功能
* 分析:從具體到抽象
* 貓:
* 成員變量:姓名饱须,年齡
* 構(gòu)造方法:有參無參
* 成員方法:睡覺域醇,吃飯
* 狗:
* 成員變量:姓名,年齡
* 構(gòu)造方法:有參無參
* 成員方法:睡覺蓉媳,吃飯
* 動物:
* 成員變量:姓名譬挚,年齡
* 構(gòu)造方法:有參無參
* 成員方法:睡覺(){},吃飯()抽象類酪呻,貓狗吃的不一樣
* 調(diào)高功能:
* 接口
* */
//實現(xiàn):從抽象到具體
//調(diào)高功能
interface Jump{
//跳高功能
public abstract void jump(); //接口中只能用抽象的方法
}
//定義抽象動物類
abstract class Animal{
//成員變量
//姓名
private String name;
//年齡
private int age;
//構(gòu)造方法
public Animal(){} //無參
public Animal(String name,int age){ //有參
this.name =name;
this.age = age;
}
//成員方法
//get和sat
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
//睡覺
public void sleep(){
System.out.println("睡覺");
}
//吃飯定義為抽象類
abstract void eat();
}
//定義具體類貓
class Cat extends Animal{
//成員變量繼承
//構(gòu)造方法
public Cat(){}
public Cat(String name,int age){
super(name, age);
}
//成員方法殴瘦,繼承睡覺
//重寫吃飯
public void eat(){
System.out.println("貓吃魚");
}
}
//定義具體類狗
class Dog extends Animal{
//成員變量繼承
//構(gòu)造方法
public Dog(){}
public Dog(String name,int age){
super(name, age);
}
//成員方法,繼承睡覺
//重寫吃飯
public void eat(){
System.out.println("狗吃肉");
}
}
//貓類實現(xiàn)跳高
class JumpImplCat extends Cat implements Jump{
//成員變量繼承
//構(gòu)造方法
public JumpImplCat(){}
public JumpImplCat(String name,int age){
super(name, age);
}
//成員方法繼承睡覺吃飯
//跳高
public void jump(){
System.out.println("貓?zhí)?);
}
}
//狗類實現(xiàn)跳高
class JumpImplDog extends Cat implements Jump{
//成員變量繼承
//構(gòu)造方法
public JumpImplDog(){}
public JumpImplDog(String name,int age){
super(name, age);
}
//成員方法繼承睡覺吃飯
//跳高
public void jump(){
System.out.println("狗跳高");
}
}
public class JiekouText {
public static void main(String[] args) {
//測試無參構(gòu)造貓
JumpImplCat cat = new JumpImplCat();
cat.setName("哆啦A夢");
cat.setAge(3);
cat.eat();
cat.sleep();
cat.jump();
System.out.println(cat.getName()+"----"+cat.getAge());
//測試有參構(gòu)造狗
JumpImplDog dog = new JumpImplDog("小白",3);
dog.eat();
dog.sleep();
dog.jump();
System.out.println(dog.getName()+"-----"+dog.getAge());
}
}
Day10
引用類型作為方法的形參
類名:(匿名對象的時候其實我們已經(jīng)講過了)需要的是該類的對象
抽象類:需要的是該抽象的類子類對象
接口:需要的是該接口的實現(xiàn)類對象
//類名作為方法的形式參數(shù)
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class StudentDemo {
public void method(Student s) { //ss; ss = new Student(); Student s = new Student();
s.study();
}
}
class StudentTest {
public static void main(String[] args) {
//需求:我要測試Student類的study()方法
Student s = new Student(); //創(chuàng)建對象
s.study(); //調(diào)用方法
System.out.println("----------------");
//需求2:我要測試StudentDemo類中的method()方法
StudentDemo sd = new StudentDemo();
Student ss = new Student();
sd.method(ss);
System.out.println("----------------");
//匿名對象用法
new StudentDemo().method(new Student());
}
}
//抽象類作為方法的形式參數(shù)
abstract class Person {
public abstract void study();
}
class PersonDemo {
public void method(Person p) {//p; p = new Student(); Person p = new Student(); //多態(tài)
p.study();
}
}
//定義一個具體的學(xué)生類
//抽象類作為方法的形式參數(shù)
class Student extends Person {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class PersonTest {
public static void main(String[] args) {
//目前是沒有辦法的使用的
//因為抽象類沒有對應(yīng)的具體類
//那么号杠,我們就應(yīng)該先定義一個具體類
//需求:我要使用PersonDemo類中的method()方法
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
}
}
//接口作為方法的形式參數(shù)
interface Love {
public abstract void love();
}
class LoveDemo {
public void method(Love l) { //l; l = new Teacher(); Love l = new Teacher(); 多態(tài)
l.love();
}
}
//定義具體類實現(xiàn)接口
class Teacher implements Love {
public void love() {
System.out.println("老師愛學(xué)生,愛Java");
}
}
class TeacherTest {
public static void main(String[] args) {
//需求:我要測試LoveDemo類中的love()方法
LoveDemo ld = new LoveDemo();
Love l = new Teacher();
ld.method(l);
}
}
引用類型作為返回值
類:返回的是該類的對象
抽象類:返回的是該抽象類的子類對象
接口:返回的是該接口的實現(xiàn)類的對象
//類最為返回值
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class StudentDemo {
public Student getStudent() {
//Student s = new Student();
//Student ss = s;
//Student s = new Student();
//return s;
return new Student();
}
}
class StudentTest2 {
public static void main(String[] args) {
//需求:我要使用Student類中的study()方法
//但是,這一次我的要求是丰歌,不要直接創(chuàng)建Student的對象
//讓你使用StudentDemo幫你創(chuàng)建對象
StudentDemo sd = new StudentDemo();
Student s = sd.getStudent(); //new Student(); Student s = new Student();
s.study();
}
}
//抽象類作為返回值
abstract class Person {
public abstract void study();
}
class PersonDemo {
public Person getPerson() {
//Person p = new Student();
//return p;
return new Student();
}
}
class Student extends Person {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class PersonTest2 {
public static void main(String[] args) {
//需求:我要測試Person類中的study()方法
PersonDemo pd = new PersonDemo();
Person p = pd.getPerson(); //new Student(); Person p = new Student(); 多態(tài)
p.study();
}
}
//接口作為返回值
interface Love {
public abstract void love();
}
class LoveDemo {
public Love getLove() {
//Love l = new Teacher();
//return l;
return new Teacher();
}
}
//定義具體類實現(xiàn)接口
class Teacher implements Love {
public void love() {
System.out.println("老師愛學(xué)生,愛Java");
}
}
class TeacherTest2 {
public static void main(String[] args) {
//如何測試呢?
LoveDemo ld = new LoveDemo();
Love l = ld.getLove(); //new Teacher(); Love l = new Teacher(); 多態(tài)
l.love();
}
}
鏈式編程
每次調(diào)用完畢后返回的是一個對象(只有對象才能繼續(xù)調(diào)方法)
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class StudentDemo {
public Student getStudent() {
return new Student();
}
}
class StudentTest3 {
public static void main(String[] args) {
//如何調(diào)用的呢?
StudentDemo sd = new StudentDemo();
//Student s = sd.getStudent();
//s.study();
//相當(dāng)于下邊的
sd.getStudent().study();
}
}
包
其實就是文件夾
作用
把相同的類名放到不同的包中
對類進行分類管理
舉例:
學(xué)生:增加姨蟋,刪除,修改立帖,查詢
老師:增加眼溶,刪除,修改晓勇,查詢
...
方案1:按照功能分
cn.itcast.add
AddStudent
AddTeacher
cn.itcast.delete
DeleteStudent
DeleteTeacher
cn.itcast.update
UpdateStudent
UpdateTeacher
cn.itcast.find
FindStudent
FindTeacher
方案2:按照模塊分
cn.itcast.teacher
AddTeacher
DeleteTeacher
UpdateTeacher
FindTeacher
cn.itcast.student
AddStudent
DeleteStudent
UpdateStudent
FindStudent
包的定義
package 包名;
多級包用.分開即可
注意事項:
package語句必須是程序的第一條可執(zhí)行的代碼
package語句在一個java文件中只能有一個
如果沒有package堂飞,默認表示無包名
帶包的編譯和運行:
手動式
編寫一個帶包的java文件
通過javac命令編譯該java文件
手動創(chuàng)建包名
把b步驟的class文件放到c步驟的最底層包
回到和包根目錄在同一目錄的地方,然后運行
帶包運行
自動式
編寫一個帶包的java文件
javac編譯的時候帶上-d即可
javac -d . HelloWorld.java
回到和包根目錄在同一目錄的地方绑咱,然后運行
帶包運行
導(dǎo)包
格式:import 包名;
這種方式導(dǎo)入是到類的名稱,注意:我們用誰就導(dǎo)誰
例:import cn.itcast.Demo //Demo為類名
package,import,class的順序關(guān)系
package > import > class
Package:只能有一個
import:可以有多個
class:可以有多個绰筛,以后建議是一個
權(quán)限修飾符的訪問
本類 同一個包下(子類和無關(guān)類) 不同包下(子類) 不同包下(無關(guān)類)
private Y
默認 Y Y
protected Y Y Y
public Y Y Y Y