小白java基礎關卡速通

前言

特別基礎,遺漏較多,在後期需要學習人員針對小標題知識點再過一遍
一段廢話:
編程與哲學、數學是密不可分的,但是數學不好能不能學,當然能學,數學就是爲了探索問題而存在,而編程是爲了解決問題,二者相似,但是解決一個問題就像築城,有很多角色,總得有不動腦的搬磚工,這個問題怎麼解決不是你考慮得,你就是一搬磚的,根據當前的制度管理與欠薪數據顯示寫代碼的跟幹工地的很相似,工信部的發文也使用過IT民工這一稱謂,一個築的是真城,一個築的是虛擬城,幹個十年,你搬磚方法爐火純青,一個磚有十八種搬法,恭喜你解決了一個了不起的問題:如何優雅的搬磚,這不是自嘲這是現狀。另外入行後平時買點保健藥,不然確實老的快,2年滄桑,5年油膩,十年禿頭,電腦藍光是不會騙人的。

java關鍵字

略;就是java語言的規則,關鍵字代表着某種秩序,後面會有編譯器對其進行語法樹的抽取之類的。

8種基礎數據類型+字符串類型

boolean、byte、short、char、 double、 float、int、long 與 String
必須死記硬背,至於32位,8bit這種詳細知識前期不作了解,會用就行

權限修飾符

private、public、protected、default(default不寫)都是權限修飾符,一般放在類名、方法名、變量前面,java有且只有這四個權限修飾符,作用是爲了限制訪問範圍,java裏的訪問範圍主要是包與類、父與子的限制,java工程裏要先建一個包(可以看作一個特殊文件夾),才能建各種類,包名爲防止重複一般是 公司域名倒置爲前綴+模塊名+功能名,例: com.duck.gaga.eatcom.duck.gaga.drink

舉個權限修飾符對包與類訪問範圍限制的例子:

包A 
   類1
     private 變量a
   類2
     protected 變量b
包B
   類3
     變量c
   類4
     public 變量d

1個包=n個類,1個類=n個方法+n個變量,類、方法、變量都可以設置被別人訪問的權限,private只能是本類訪問,so想操作變量a只能在類1裏,變量d是public的是全局公開的,在類1、2、3都可以對變量d進行讀取、修改之類的,後期自會理解深意,前期會用即可,default就是不寫,譬如int i=0;沒有權限修飾符,其實就是default,實戰中除了protected其它比較常用,private存在的意義之一就是類裏內部自用的方法儘量不要被外部看見,so用private修飾。

條件語句

當人嘲諷的時候順口而出的就是,不就是if-else麼有什麼難得,說得就是這個條件語句,java條件分支語句共兩種if-else、switch-case

if-else寫法:

if(判斷1){ //判斷1一般我們稱爲表達式

}else if(判斷2){

}else{

}
int n=0,j=1,e=3;
int i=1;
if(n>1){
  //n>1時走這個邏輯分支,其它分支自動跳過  
}else if(i==1){
  //i==1時走這個分支
  if(j<0){
     if(e>=3){
       //if語句可以嵌套,但是不宜過深嵌套過深會導致邏輯過於複雜
     }
  }
}else{
  //上述if都不匹配走這個else分支,else分支不是必須的,可以沒有
}

有人問如果n>1,i==1的條件都符合怎麼辦?
答:if-else分支按照從上至下的順序順位執行,哪個條件先符合進入哪個分支,其它分支跳過,
譬如n=2,i=1時上述n>1的分支先進入,則其之後的i==1的邏輯分支就不會執行了,
switch-case:

switch(變量){
  case 常量值1:
    break;
  case 常量值2:
    break;
}

break是java的高頻關鍵字,中斷的意思,哪裏都能寫,萬金油的角色,條件分支中代表着退出整個條件判斷,如下寫法1,
grade爲'A'時,控制檯輸出“優秀”,退出整個switch判斷。
grade爲'B'時,控制檯輸出

上等
良好

因爲'B'、'C'之間沒有break;執行完'B'邏輯後,邏輯沒有退出會往下順序執行'C'的邏輯
爲'C'時輸出結果爲“良好”,default是switch的語法,當所有條件不滿足時會執行它這塊邏輯,也可以省略,省略後代表當前分支邏輯沒有缺省狀況

      char grade = 'C';
//寫法1(完整的):
      switch(grade)
      {
         case 'A' :
            System.out.println("優秀"); 
            break;
         case 'B' :
            System.out.println("上等");
         case 'C' :
            System.out.println("良好");
            break;
         case 'D' :
         case 'E' :
            System.out.println("及格");
            break;
         case 'F' :
            System.out.println("你需要再努力努力");
            break;
         default :
            System.out.println("未知等級");
      }
//寫法2(常用寫法):
int fee;
switch(fee){
  case 1:
     System.out.println("請支付1元");
  case 10:
     System.out.println("請支付10元");
     break;
  case 10000:
     System.out.println("您支付不起,請出門左轉,記得關門麼麼噠!");
     break;
     
}
變量定義

語法固定格式:權限修飾符+數據類型+變量名,但是方法裏的變量定義不使用權限修飾符(因爲在後面的知識點會對變量進行分類,成員變量,靜態變量之類的,已經約束了其使用範圍,java的設計者就不會再對其進行修飾符的訪問限定)

public void duckSay(){
 //這裏的變量不用修飾符,會報錯,它的使用範圍是在當前方法內
 int i=4;
}

變量的定義是1.聲明 2.賦值;可以先聲明不賦具體值如private int fee;,在某個方法或者某個地方進行具體賦值,也可以連寫在定義時就進行賦值private int fee = 5;

private int fee=5;
float miniFee=1.2f; //float數字後需加f表示浮點型
int[] oneFee={3,5}; //數組是特殊對象類型,學習完封裝類後解鎖
public static String = "天地玄宗,萬炁本根";
java裏的數據類型有如下幾種:
1、8種數據類型
2、對象類型(在學習面向對象的知識後解鎖這種類型知識)
static是關鍵字也是修飾符,作用是免去實例化,在學完面向對象的實例化知識後解鎖,當前僅作了解
運算符

java裏的運算符大致可分爲:算術運算符、關係運算符、位運算符、邏輯運算符、賦值運算符、其他運算符
算數運算符:就是+-x% ++(自增運算符) --(自減運算符)
自增運算符:不用糾結++i還是i++這種問題,for循環打印出值時候自然就會了。

for(i=0;i<5;i++){
   int n=6;
   i++;
}

關係運算符:一般用於if語句裏,==、!=、>、<、>=、<=小學數學。

int i=0;
if(i++>=3){
  //滿足條件進入
}

位運算符:表層開發一般難以用到,忽略。
邏輯運算符:常用的爲&&、||、!,一般用於if語句裏,大致有&、&&、|、||、!
&&稱爲“邏輯與”英文and的意思,||爲“邏輯或”英文or的意思,!爲“邏輯非”英文not得意思

if(i>3&&n<5){
  //兩者都符合才進入
}
int k=5;
if(!k>5){
  //邏輯非就是對true、false取反的意思,此處對k>5進行取反意思爲k<=5,故符合條件。
}

注意,!false的邏輯結果是true,邏輯假+邏輯假=邏輯真,真假爲假,假真爲假,真真爲真,高中的知識,此處若看不懂沒關係,一句話就是左邊條件與右邊條件共同作用產生的邏輯結果,寫兩行一眼就會。
問:&&&有何區別?
答:&&具有短路的作用,譬如 if(n<1 && fee<50){}
左邊的n若爲false &&此時就會短路不會再判斷右邊邏輯即fee<50,但是&會再次判斷造成計算資源浪費,||也類似具有短路功能。

三目運算符:固定格式:V=A>B?C:D,?:是兩個關鍵字符
三目運算符是對if else語句的簡化,意思爲 A>B?是的話V=C,否的話V=D。

//舉例
int num1=5;
int num2=4;
int V;
int fee1=1;
int fee2=2;
V=num2>num1?fee1:fee2;//因爲4<5,邏輯是假,所以取值fee2,故V的值爲2

instanceof 運算符:這個運算符是java語言定義的關鍵字,作用就是判斷對象是否相等,譬如,

int i=5;
if(i instanceof Integer){
  
}

此處結果爲真i的值所對應的對象類型確實是int類型的封裝類,封裝類就是8種基礎數據類型都對應着一個java對象,這些封裝類專門服務於基礎數據類型系列裝箱拆箱操作或者其它輔助打雜的東西,具體可以搜java封裝類

方法定義

說明:java裏的方法就是C語言裏的函數,稱謂不同,用法也跟C語言相似
語法固定格式:權限修飾符 + 返回值類型 + 方法名(n個入參)

    public void computeFee(){
       //這裏叫方法體
       computeFee2(100,5.8f);//這就是方法間的調用
    }   
    public void computeFee2(int i,float n){
        i=i+1;
        n=n+2;
    }

方法名後面用括號把入參括起來是固定寫法,多個入參之間用英文逗號分割

循環語句

java得循環語句總共有三種whiledo-whileforfor-eachfor的增強版不算單獨種類,自己擇機而用,按照實際使用頻率排序爲for>while>>do-while,do-while實戰至今我就見過一兩次。

while:

int i=0
while(i>0) {
  //循環內容
  i++;
}

do-while:

do{
  //循環內容
}while(i>0);

while與do-while的區別是do-while功能=先走一遍循環內容+while的功能,會先走一遍循環的邏輯後再進行是否循環的邏輯判斷,不符合就退出,所以出場率不高,while足矣。
for:

//寫法1:
int fee;
for (int i = 0; i < 150; i++) {
    //循環體
    if (i > 100) {
      break;
    } else if (i > 80 && i < 100) {
      continue;
    }
    if (fee > 10000) {
      return;
    }
    fee = fee + 10;
}
//寫法2爲for的增強循環,基本是從數組或集合中取東西,此處略(集合java裏是一種大小可變的特殊數組)

for一般寫法就是下標循環,也就是示例的寫法足以覆蓋絕大部分業務。
問:循環怎麼跳出來呢?
答:關鍵字breakreturn進行跳出整個循環,若只是想中斷某一次循環的話用關鍵字continue,
這三者有啥區別?
breakcontinue的區別就是break是跳出當前整個循環邏輯,continue是跳出本次循環在continue後面的代碼本次執行不到了,下一個循環再見,return是方法的返回值,方法一旦返回別說本次循環,是整個方法都跳出了,當方法返回值是void時寫return;有具體返回值類型返回對應的類型值

int fee;
public int myFee() {
  for (int i = 0; i < 150; i++) {
     //循環體
     if (i > 100) {
       break;
     } else if (i > 80 && i < 100) {
       continue;
     }
     if (fee > 10000) {
       return fee;
     }
     fee = fee + 10;
   }
  return 0;
}
數組

數組在運行時是對象,寫法上跟普通對象有些不一樣,數組在內存中是一段連續的內存區域,所以在使用前需要定義好大小讓系統去開闢內存,數組寫的時候跟變量意義先聲明再賦值也可以連寫,在實際運行後就變成內存裏的實體,大小不可更改,萬物皆可數組,數組下標(index)從0開始,so數組中第1個元素的index=0,第2個元素index=1。數組可以理解爲數據水桶,你要多少毫升的提前說好我鑄造好了就沒法改了。

幾種寫法格式,自己挑一種

//寫法一:
float[] fee2 = new float[]{2.0f,3.4f,5.5f,3.2f};//表示聲明一個float數組元素,
//此處沒有聲明容量,直接用元素填充了,元素具體值都有了,自然不用再贅述容量了
//寫法二:
long[] fee3 ={3,5,29,67};//這是省略版寫法,與fee2相同簡化部分由編譯器補全
//寫法三:
AnObject[] obj = new AnObject[15];//一個類名叫AnObject的對象數組,容量爲15
int[] fee1 = new int[10]//表示聲明一個名爲fee1的整型數組,元素儲量爲10,裏面元素待添加,
//實戰意義較大,因爲實戰中只需要聲明水桶不需要數據,數據後續邏輯執行會添加
//賦值寫法
fee1[0]=20;//表示在數組下標0這個地方賦值,值爲20,
//取值寫法
int myFee = fee1[0]//這個myFee值就是20.

下圖是java語句,循環用的增強for循環即foreach,做數組練習足以,解出手機號爲18013820100

上圖代碼等於

int[] arr = new int[]{8,2,1,0,3};
int[] index = new int[]{2,0,3,2,4,0,1,3,2,3,3};
String tel="";
for (int i = 0; i < index.length; i++) {
    tel=tel+arr[i];
}
System.out.println("聯繫方式爲:"+tel);
  • Number與Math類

    上面說過基礎數據類型都對應着一個輔助的封裝類幹各種雜事,基礎數據類型的封裝類除了char與boolean其餘都繼承自Number,學完面向對象後理解更深,此處需強行記憶。
    此處略,需要寫程序做習題運行才能理解,屬於理論必知,看詳情https://www.runoob.com/java/java-number.html
    練習題:
    習題1:已知一個圓的半徑r=15,求圓的面積,結果用整數表示,π按3.14算。(整數保留使用強制類型轉換)
    習題2:將習題1的整型結果乘以1.0,1).求出平方根,2).對比平方根與習題1實際結果兩個數值的大小(使用Math類)3).對習題1結果四捨五入轉爲整型。

    習題的結果將會把浮點型轉爲整型,這種轉換就是由封裝類的拆箱封箱操作的,屬於理論必知。
double k=1000.234;
int price = (int)k;//這就是強制類型轉換的寫法,四捨五入屬於Math類的特殊算法需要使用Math類的方法
關於文字的封裝類

Character是char的封裝類,爲char類型處理各種雜事,字符用單引號括起來書寫爲`F`,每個字符對應着Ascii編碼.
練習題:對比字符串“a1sdcd3r%”相鄰兩個非數字字符的大小,並打印出對應的數字,提示->需要用到知識涉及:數組,for循環,字符串轉字符數組,Character類(自己查詢可用類裏哪些方法)

String

String比較特殊,它是字符串不是基本數據類型是引用數據類型,它超高頻很重要,典型的問法就是
String hai = new String("hellow!");產生了幾個對象。
java中+號就可以實現類型轉換和字符拼接。

int fee=500;
String priceList = fee+"";
String preffix = "價格清單:"+priceList ;

+""是拼接一個空字符串的意思,我們在書寫中經常在數字類型後面寫這個以讓結果轉換爲字符串,通常在for循環中字符串拼接。
StringBuffer (一般)線程安全的,可多線程使用,速度略低於StringBuilder;
StringBuilder(高頻)線程不安全,單線程使用,速度快,一般都是它,多用於循環語句中的字符串追加拼接。
兩者差別可百度“StringBuffer與StringBuilder”的區別

面向對象
  • 概念:軟件設計一般都源於生活與哲學,面向對象的概念源自哲學理念“萬物皆對象”這句話,其跟“Hello World!”是每一個學java的人都知道的名言,就像《權遊》粉都知道的“Winter is coming”、“凡人皆有一死”。面向對象理念認爲所有的東西都可以看作一個研究對象,這個對象可以是貓、狗這種具體的,也可以是職業、死亡這種抽象的,所以面向的其實是一個個研究對象。
  • 問:一個研究對象裏有什麼呢?
    1.屬性:譬如研究房地產,它有自然屬性與經濟屬性,這兩個大的屬性還可以繼續拆分。譬如物理研究物體,質量就是每個物體最重要的一個屬性。研究人,胳膊、腿、髮量都是人自有的,可以看作人的屬性,屬性需要被挖掘被定義,是這個對象所攜帶的東西,你對這個研究對象自有的東西進行定義就是定義屬性。
    2.動作:無論具體的抽象的,活的死的一個研究對象總可以做點什麼,這個在java中就是對象裏的函數(java叫方法),我們用對象裏的方法去做一些事,譬如人這個對象可以喫,喫就是一個動作,走路,喝水都是動作,喫、走路、喝水就是人這個對象的方法。
    總結下研究對象的屬性、行爲,對應着java裏的屬性、方法。
  • 問:java類與對象是什麼關係?
    類很多人解釋爲圖紙,對象解釋爲實體,我給來解釋,假設你是一個工程師,類它就相當於你在紙上畫畫(類寫在.java文件中,可以把.java文件看作紙張),你定義了它是什麼,有哪些屬性,可以做什麼,程序運行時計算機會按照你定義的關係進行構造並存儲在內存中,內存中的這個能實際起作用的東西就是我們心心念念叫的對象,對象它是一個實體,
    舉個例子:你寫小作文定義了老頭樂的屬性與方法,廠家把老頭樂出來,這個老頭樂實體就叫對象,你的小作文就是類,廠家是計算機,造對象的這個行爲我們叫做實例化,所以對象是一個類的實例,java裏實例化的關鍵字是new,故沒有對象new一個對象就行了,經常有人說你沒有對象?new 一個就行了。實例可以理解爲實體例子,“實例化”這個化跟“自動化”這個化意思差不多表示轉變成某種性質或狀態。
    我在概念階段把對象稱爲研究對象,有了實體以後我才稱爲對象(Object),在圖紙定義階段稱爲類(Class),用三種稱呼進行區分新手容易理解。
    將類變成對象代碼示例:
    假使需要實例化的類名叫LiuYiFei
固定語法格式:
數據類型 接收對象的變量名 = new 類名();
//1個類也是一個數據類型,除了8種基礎數據類型外,我們寫的類也是數據類型
LiuYiFei liuSir = new LiuYiFei();
這句話的意思是實例化一個劉亦菲並賦值給變量liuSir,這種賦值跟int oneChui=80;是差不多的意思
  • 問:liuSir與oneChui有和不同?
    解釋之前需要說個題外話,機器在運行程序時除了cpu運算還需要臨時存儲運算值,存儲的地方就是運行內存(RAM),我們買電腦時說的內存多少 說的就是這個東西,但是程序運行時數據存的策略還需要人去定義,這個定義人就是管理Java虛擬機的大神,有一種工作叫JVM調優,絕大部分情況下我們用的是默認的java內存模型,可以百度瞭解下。
    比較這兩個有啥不同此處就得引入一個概念引用數據類型,其實說的問題就是 基礎數據類型引用數據類型 有啥不同?比較這兩個東西需要引入內存模型,棧與堆。
    學過數據結構的知道棧這個東西就像一個量桶(注意量筒不是量杯,初中化學實驗的量筒),它存儲值就像把麻將一個一個丟進去,先進後出的特性註定了要找裏面的東西只能一個個倒出來再塞回去,那麼爲了運算速率它就不能太大,太大不好查找遍歷,它是系統自動分配的,而堆就是垃圾堆大的一批浩如煙海宛若星辰,可以理解爲數據池塘,它是實例化對象的時候申請的空間,相當於每次人爲向系統申請開闢,多了就成了垃圾堆。
    基礎數據類型(下面簡稱基類):int是java8種基類之一,oneChui就是麻將它存儲在棧中,棧中直接存儲得二進制值,所以“麻將”就是具體值。
    引用數據類型:LiuYiFei已經new了,就是實例化了,是個內存中的實體對象,它的內存佔用太大放在堆中,那麼堆太大需要用到LiuYiFei時要查找整個池塘那太費勁了,怎麼辦,那就用量筒中的麻將記錄他在池塘的具體位置,所以變量liuSir的值就是量筒中的麻將,注意,liuSir是你定義的變量名是名字,他在語法中叫引用變量(變量指向1個對象就叫引用變量),它的值存儲在棧內存中,此處將其棧中的值舉例爲“麻將”,它跟基類的不一樣,基類的麻將就是具體值,liuSir的值是一段堆內存的地址,即一個叫liuSir的引用變量的值是一段堆內存地址,那個堆地址上放着的值纔是對象的實體,這就跟C語言的指針類似了,所以一般聽到的描述是引用指向對象,這個引用就是麻將(liuSir的值),像個代理,通過它存的地址我們能直接訪問對象裏的方法屬性等,譬如liuSir.eat("西瓜");,梳理一下,引用數據類型的變量值與基類的變量值一樣存儲在棧中,但是值跟值不太一樣,基類存的是具體的二進值,引用類型存的是一段堆內存地址,沒有直接在棧中存儲對象實體,它太大了,那個堆內存地址上的二進制值纔是對象實體;我們開發時說引用訪問對象,就是通過“麻將”訪問了對象,像一個指針指向一個地址。量筒是棧,麻將是變量的值,池塘是堆,堆內存地址上的值是對象實體,通常開發時說某某類的引用其實就是說這個類對應的實體,譬如,變量liuSir持有了LiuYiFei的引用。
類:

java類有哪些概念
封裝、繼承、多態
劃重點,這是面向對象的三大特性,是相對於面向過程的語言說的,這個很重要是java語言的立國之本,類在寫的時候需要考慮這三大特性,故在此處才說。

  • 繼承: 就是兩儀生四相,四相生八卦,有着父子關係,跟你熟知的遺產繼承差不多,程序執行時先執行父類邏輯再執行子類,父類非private修飾的東西子類都可以繼承,父子關係存在的意義就是爲了擴展,譬如:十年前造了一輛五菱之光,五年前基於五菱之光造了五菱宏光,現在基於五菱宏光造了五菱神光,在之前的基礎上再擴展可保持了原有邏輯的完整性,又有新邏輯可用,有人說我都有了五菱神光爲啥還要保持五菱之光邏輯,假設五菱之光便宜但是醜,五菱神光顏值高但是貴,今天我要去送葬那麼我肯定得用五菱之光,因爲便宜,保持它得邏輯就是保留了使用得可能性,所以繼承得核心是既保持原有邏輯不動,又有新東西可用,在書寫上繼承使用關鍵字extends,體現在代碼上書寫爲:
    分別建四個.java文件書寫四個類,類名分別命名爲CarWL、CarWLZG、CarWLHG 、CarWLSG ,.java的文件名須與類名一致
//CarWL.java文件  五菱
public abstract class CarWL{
   public String name = "五菱系列";
}

//CarWLZG.java文件  五菱之光
public class CarWLZG extends CarWL{
   public int windowCount = 4;
   public int luntaiCount =3;
   private int ugly=100;
   public void drive(){
      System.out.println("敞着開");
   }
}
//CarWLHG .java文件  五菱宏光
public class CarWLHG extends CarWLZG{
   private String color = "#ffffffff";
}
//CarWLSG.java文件  五菱神光
public class CarWLSG extends CarWLHG {
   private int music = 5;
   @Override
   public void drive(){
      System.out.println("優雅的開");
   }
}

通過上面三個類可以發現,五菱宏光(CarWLHG)只定義了一個顏色,但實際上因爲它繼承自五菱之光(CarWLZG),所以它實際擁有了五菱宏光(CarWLHG)public修飾的部分,完整爲windowCount 、luntaiCount 、color以及一個drive()方法 ,private修飾的東西無法被繼承,所以醜就沒被繼承下來,有人問繼承的東西能不能改動,當然可以,如上代碼五菱神光(CarWLSG)這代就把開車方式給改了,以前都是敞着開到了神光這一代我就得優雅的開,這種改動涉及到一個java語法概念覆寫又叫覆蓋重寫,在方法上方加一個@Override關鍵字,表示對父類的方法進行方法體邏輯的重新定義。
總結:其實繼承這個描述的本意我認爲是將共性的東西向上抽取,動物->人->男人、女人,屬於這種共性抽取的繼承關係,越往下描述的越具體,源於生活卻高於生活,這體現了一種由0到100的梯層設計,每一梯層都能滿足一層的需求,這個需求其實就是做什麼,定義對象的目的其實就是定義這個對象能做什麼。

  • 多態: 又叫變態,“冰水爲之卻寒於水”,這就是一種多態,三大特性就是哲學概念,一個事物不可能永遠只能是一中形態,就譬如你的爺爺是你曾祖的兒子,是你爸爸的爸爸,有着多種存在形式,假設有這樣一層繼承關係Steam(水蒸氣)➼ICE(冰)➼Water(水),水既是冰也是水蒸氣,再舉一個例子,狗既是狗也是動物,一個抽象物體會有多種表示形態,這就是多態的含義,它存在的意義就是兩字“共性”與多樣性,一個東西被多個實現,一氣化三清,三清就是一氣的多態,舉個例子:我在一個類裏定義一個變量爲五菱的車,那麼是不是用五菱系列的之光、宏光、神光都可以,它們都是五菱車,上代碼
上述五菱的例子有這樣一層繼承關係
CarWLSG➼CarWLHG➼CarWLZG➼CarWL
//CarShow.java文件
public class CarShow{
  public void show(CarWL  carWl){
    System.out.println("展示五菱的車"+carWl.toString);
  }
}

//CarFactory.java
public class CarFactory{
  public void doAnCarShow(){
     //對象裏方法的調用就是用  引用變量.方法
     CarShow carShow = new CarShow(); //實例化一個車展的對象(車展對象專門負責展示車)

     CarWL carWL = new CarWLSG(); //實例化一輛五菱神光,並用五菱車類型進行接收
     carShow.show(carWL); //車展對象做展出,展出的東西爲五菱神光

     CarWL carWL = new CarWLZG();//實例化一輛五菱之光,並用五菱車類型進行接收
     carShow.show(carWL);  //車展對象做展出,展出的東西爲五菱之光
  }
}

1.向上轉型: 上述代碼描述的就是多態的典型在代碼裏的實際運用, 將子類對象賦值給父類類型的變量,這種技術稱爲“向上轉型”;
使用場景:有時候我們只知道要展示某一類型的車但不知道具體展示什麼,那麼我們就可以用這一類車的公用父類定義參數類型,這種場景在封裝功能時經常會用到,但是向上轉型後具體類型的特有屬性就無了,譬如展示的之光用五菱類型去接收,那麼它只剩下了name這一屬性,只能對name這屬性進行操作,其它屬性都丟失了,因爲CarWl沒有CarWLZG的屬性與方法,這個類型的變量只有carWl.name
2.向下轉型: 父類引用的對象轉換爲子類類型稱爲向下轉型

//第一種:
CarWL carWL = new CarWLZG();//new1個五菱之光用五菱類接收
CarWLSG carWLSG = (CarWLSG)carWL;//強制轉換爲五菱神光
//第二種:
CarWL carWL = new CarWLSG();//new1個五菱神光用五菱類接收
CarWLSG carWLSG = (CarWLSG)carWL;//強制轉換爲五菱神光

上述兩種都是向下轉型,就是把父類對象強制類型轉換爲具體子類,譬如我定義一個五菱類型變量,由於五菱是五菱之光與五菱神光的父類,所以你傳之光對象或者神光對象都行,我接收之後都轉爲神光,神光中有個music屬性,我就用神光播放音樂,有人問這不是神經病麼,不能直接傳入神光麼,因爲我不知道後續會不會有類似神光這種五菱系列的車可以播放音樂,爲了保持擴展性,在定義時我用共性的父類肯定沒有問題,我的需求是播放音樂,如果車輛沒有音樂功能,則它是一個缺省數據不影響我的功能,功能保持開放,選擇歸數據,這就是向下轉型的作用,就是接收一個模糊的數據以備後用,這種也是封裝功能的時候用的多。
總結:多態核心掌握就是向上轉型,向下轉型,有人問這種值不會丟失麼,不管是向上轉型還是向下轉型都會丟失一些精度,這是正常的,那爲什麼還要這麼用呢,因爲數據操作本身都是目的性的,最差也有缺省值,所以實際使用中功能不會有啥影響,這一段到後期寫一些泛型的封裝自會理解。

  • 封裝: 這個東西比較好理解,就是模塊化,把對象的設計細節給隱藏起來,外界想訪問只能通過你提供的窗口,舉例:
public class LanApple{
   private int color;
   private int wide;
   private int high;
   public void changeColor(int color){
      System.out.println("顏色改爲:"+color);
   }
    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public int getWide() {
        return wide;
    }

    public void setWide(int wide) {
        this.wide = wide;
    }

    public int getHigh() {
        return high;
    }

    public void setHigh(int high) {
        this.high = high;
    }
}

這種就是一種封裝,隱藏自身信息或實現細節,外部只能通過你定義的窗口進行訪問無法直接操作,有人問我直接看源碼不就都知道了,還能隱藏啥,幹嘛不能直接訪問變量,假使第三方公司給你一個sdk(軟件開發工具包,都是編譯後的字節碼)不給源碼只有訪問的API(開放接口)這時候你就只能調用別人開放的接口,因爲別人隱藏變量了信息,你不知道有啥可以拿,上述例子我改一下,把getHight改爲panChangJiang,這個時候別人不知道你獲取的是什麼東西,你只能去查他寫的解釋,他不解釋你永遠不知道這是身高,你還以爲是最小高度值,有序的告知防止人人知曉,曉得越少越安全。

public int panChangJiang() {
    return high;
}

再舉個例子:

private BigFruitsBasket {
  private LanApple apple;
  private LanPear pear;
}
public class Gift {
  private BigFruitsBasket fruits;
  private DrinkBasket drink;
}

我定義好了一個送禮物的類,禮物有大水果籃子、飲料籃子,水果裏有爛蘋果跟爛梨子,我這時候想改一下禮物把爛梨子換成爛李子(plum),只需要改BigFruitsBasket ,Gift 就不用動,如果我不分類封裝BigFruitsBasket這個類,把它這些水果寫在Gift裏面,禮物如果非常多,就會很容易改錯而且不容易管理,我今天改水果,張三明天改飲料,每次修改禮物都要修改Gift,代碼很容易改衝突,所以封裝有句名言“高內聚,低耦合”這6個字就是封裝的核心靈魂之一,在寫的時候要想好一個功能可以拆分爲幾個對象,各個對象之間能做什麼,怎麼調用這種就是封裝,模塊化就是目的,模塊與模塊之前的關聯越少越好就是低耦合,高內聚就是把功能越多越好的封裝在自己內部。
1、封裝有利於提高程序的安全性,保護數據
2、隱藏代碼的實現細節,用戶不可見
3、統一了接口
4、增加系統的可維護性

  • this與super
    this代表當前對象的引用
    super代表父類對象的引用

  • 變量

  • 方法
    類裏的三大特性說完了,再回頭說說類裏的方法,上面寫了方法的定義,這裏完善方法的知識
    1.構造方法
    語法格式:修飾符+類名+(若干參數);
    構造方法又稱構造器,是一種特殊的方法,方法名必須與類名相同,且沒有返回值。對象的創建就是通過構造方法來完成。
    有幾個需要強記的知識:
    a.每個類默認有一個無參構造方法,所以創建類後也可以不寫
    b.構造方法的參數可以用來做成員變量初始化,見下方源碼
    c.構造方法和普通方法一樣也可以重載,想寫幾個寫幾個,但是寫了有參構造方法,默認的無參構造方法就會被取消需要你自己去實現,譬如下面的LanApple我寫了雙參數的構造方法,又寫了無參構造方法。

//People.java
public class LanApple{
  public void buy(){
    LanApple apple = new LanApple();
    LanApple apple2 = new LanApple("原諒色",50);
  }
}
//LanApple.java
public class LanApple{
  private String mColor;
  private int mWidth;
   public LanApple(){
      System.out.println("無參構造方法");
   }
   public LanApple(String color,int width){
      this.mColor=color;
      this.mWidth=width;
      System.out.println("雙參構造方法");
   }
}

2.虛方法與非虛方法
靜態方法、私有方法、final方法、構造方法、父類方法都是非虛方法,java中的普通方法都是虛方法可被子類覆寫,在其它語言中譬如C#需要使用virtual關鍵字纔有這個能力。
3.靜態方法
在java中,靜態方法指被static修飾的成員方法。靜態方法不需要通過它所屬的類的任何實例就可以被調用,因此在靜態方法中不能使用this關鍵字,也不能直接訪問所屬類的實例變量和實例方法,但是可以直接訪問所屬類的靜態變量和靜態方法。

4.抽象方法
5.方法的重載
6.方法的覆蓋
有幾種方法不能被重寫:
1)靜態方法:static修飾的方法,父類的靜態方法不可以被重寫,可以繼承;
2)final修飾的方法:父類中final修飾的方法不可以被重寫,可以被繼承;
3)構造方法:父類的構造方法不可以被重寫,也不需要覆寫父類構造方法;
4)private修飾的:因爲父類中private修飾的方法子類不可見;

  • 書寫
    幾個注意點,java裏類名用大駝峯 AnObject、BookManager,變量名用小駝峯anObject、bookManager,常量、靜態變量、枚舉用大寫中間用下劃線分割
public static int PEER_CONNECTION = 10;
public static int QINGDAO_BEER = 5;

類裏面的內容怎麼寫

package com.book.testsourcecode;
public class AnJava {
   //寫代碼的地方
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章