2022-02-23

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)鱼冀,選擇結(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格式1流程圖
/*
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格式2流程圖
/*
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格式3流程圖

if語句的使用場景
針對結(jié)果是boolean類型的判斷
針對一個范圍的判斷
針對幾個常量值的判斷

switch語句

/*
switch語句格式:
switch(表達式) {
    case 值1:
       語句體1;
        break;
    case 值2:
       語句體2;
        break;
        …
    default:    
       語句體n+1;
       break;
}
*/

switch語句流程圖

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);
  }

}

for循環(huán)流程圖

while循環(huán)語句
格式:
基本格式
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í)行


do while循環(huán)流程圖

循環(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)用過程

方法的注意事項:
 -方法不調(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使用)

java內(nèi)存分配圖

數(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)存圖

對象的內(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市描融,隨后出現(xiàn)的幾起案子铝噩,更是在濱河造成了極大的恐慌,老刑警劉巖窿克,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骏庸,死亡現(xiàn)場離奇詭異毛甲,居然都是意外死亡,警方通過查閱死者的電腦和手機具被,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門玻募,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人一姿,你說我怎么就攤上這事七咧。” “怎么了啸蜜?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵坑雅,是天一觀的道長。 經(jīng)常有香客問我衬横,道長无虚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任铃在,我火速辦了婚禮须床,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘噪叙。我一直安慰自己矮锈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布睁蕾。 她就那樣靜靜地躺著苞笨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪子眶。 梳的紋絲不亂的頭發(fā)上瀑凝,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機與錄音臭杰,去河邊找鬼粤咪。 笑死,一個胖子當(dāng)著我的面吹牛渴杆,可吹牛的內(nèi)容都是我干的寥枝。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼磁奖,長吁一口氣:“原來是場噩夢啊……” “哼囊拜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起比搭,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤艾疟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔽莱,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡弟疆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盗冷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怠苔。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仪糖,靈堂內(nèi)的尸體忽然破棺而出柑司,到底是詐尸還是另有隱情,我是刑警寧澤锅劝,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布攒驰,位于F島的核電站,受9級特大地震影響故爵,放射性物質(zhì)發(fā)生泄漏玻粪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一诬垂、第九天 我趴在偏房一處隱蔽的房頂上張望劲室。 院中可真熱鬧,春花似錦结窘、人聲如沸很洋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喉磁。三九已至,卻和暖如春官脓,著一層夾襖步出監(jiān)牢的瞬間线定,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工确买, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纱皆。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓湾趾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親派草。 傳聞我的和親對象是個殘疾皇子搀缠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容