1. 程式人生 > >2 面向對象

2 面向對象

關系 a-z 編寫程序 引入 駝峰 模板 private bst 封裝

面向對象的內容:

類: 相同對象或者相同事物的一個公同特點的抽象。

   類只是一個概念一個描述。類可以認為是虛擬的,不是真實存在的。

對象(實例): 具體存在的一個對象,每個人都是一個對象,是人類的一個對象
           對象是真實存在的,每個具體存在的事物都可被認為是對象。
             對象也稱之為實例。

2.類 定義類


[修飾符] class <類名稱>{ 類:有且僅有5種成分。 // 成員變量(Field) 可以出現 0 ~N個 // 構造器 可以出現 0 ~ N個 // 方法 可以出現 0 ~ N個 // 代碼塊 可以出現 0 ~ N個 // 內部類 可以出現 0 ~ N個 }

修飾符: 省略,public、final|abstrac。
類名稱:首字母大寫,"駝峰模式"
    類的成分:成員變量(Field),構造器,方法,代碼塊,內部類
類的作用:

1.定義成員變量 2.定義方法 3.定義構造器 4.可以通過類的構造器創建對象 5.調用static修飾的成員變量或者方法。 6.類可以被繼承-後面的內容

成員變量 1、用來描述類的特征狀態或者屬性的變量。 格式:[修飾符] <數據類型> 變量名稱 [= 初始值];

修飾符: public|protected|不寫|private、static、final
數據類型:基本數據類型和引用類型 變量名稱: 合法的標識符,首字母一般小寫,"駝峰模式",一般是名詞

一般來說程序員只需要定義程序關心的成員變量(狀態)即可.

2、java中4中修飾符分別為public、protect、default、private,他們這就說明了面向對象的封裝性,所以我們要適用他們盡可能的讓權限降到最低,從而安全性提高。

下面詳細講述下它們的訪問權限問題。(同一個類中除內部類外所有修飾符都是可以訪問的,所以下面排除這種情況。)
 首先在這裏把它們的訪問權限表示出來:

訪問權限   類     包    子類  其他包

public        ∨     ∨    ∨      ∨

protected   ∨    ∨    ∨      ×

default       ∨    ∨    ×      ×

private       ∨    ×    ×      ×

4.局部變量 5.方法 用來描述類或者對象行為的。

格式: [修飾符] <返回值> 方法名稱(形參列表){ // 方法體 }

修飾符: public|protected|不寫|private、static、final|abstract
  返回值:基本數據類型,引用類型, void(空:無返回值)
  方法名稱 : 合法的標識符,首字母小寫,"駝峰模式" ---> startSing(); 一般方法名稱是一個動詞
  形參列表: 格式 :  (類型 形參變量 , 類型 形參變量, 類型 形參變量 ,)

  註意事項:
      1.方法必須定義在類下面,不能放在其他地方 :因為方法是類的成分。
       2.如果方法申明了返回值類型,方法中必須存在有效的return語句。

6.方法詳解 方法不能獨立存在,方法屬於類的成分,方法只能放在類下面。

方法的形參列表用於接收傳遞過來的參數

1.方法的參數傳遞機制:值傳遞   
      對於基本數據類型,就是將值傳遞給方法的形參
  對於引用類型的數據,只是將引用類型的地址復制一份傳遞給方法的形參
  java不是傳遞對象的,而是傳遞引用的。所以是值傳遞。

  2.形參可變的方法      
         可變形參格式: 類型...  變量

         [修飾符] <返回值> 方法名稱(形參列表){
               // 方法體
          }

      可以傳遞任意多個對應類型的參數都可以。
      也可以直接傳遞一個對應類型的數組給方法。

      當有多個形參的時候,可變形參只能放在形參列表最後一個位置。

 3.方法的遞歸     
    遞歸算法是一種直接或間接地調用自身的算法。在計算機編寫程序中,遞歸算法對解決一大類問題是    十分有效的,它往往使算法的描述簡潔而且易於理解。

 4.方法的重載 
    兩同一不同。
     在同一個類中,方法名稱相同,形參列表不同就是方法的重載。

    註意事項:
          1.形參列表相同,形參變量不同不算重載
        2.形參列表相同,返回值不同不算重載
        3.調用重載的方法,只能識別一個就算重載。

7.堆棧 局部變量的數據存在於棧內存中。棧內存中的局部變量隨著方法的消失而消失。 成員變量存儲在堆中的對象裏面,由垃圾回收器負責回收。 8.構造器 構造器的作用:創建對象的,並且可以給對象實例化一些初始值。

格式:[修飾符] 類名稱(形參列表){ // 執行代碼 }

修飾符: public|protected|不寫|private   

     類名稱:必須是當前類的名稱一字不差:大小寫完全一致。

     形參列表: (類型 變量 ,類型 變量 , .....)

     註意點: 1.構造器的名稱必須與類的名稱一字不差:大小寫完全一致
                   2.構造器與方法極為相似但是構造器沒有返回值申明。
                    3.構造器也必須放到類下面,不能定義在其他成分中。
方法重載:(同一個類中,方法名稱相同,形參列表不同)

構造器重載:(同一個類中,方法就是類名稱,形參列表不同)

this(參數值列表):在同一個類的構造器中調用其他的構造器 
                 -- 具體調用哪個構造器根據參數值列表確定
                    -- this調用必須放在構造器的第一行!!!

9.創建對象 使用類的構造器創建對象 : new 構造器;

格式:類名 對象變量 = new 構造器;

 創建對象是通過new 構造器實現的:
 註意: 新建一個類默認就自帶了一個無參數的構造器,程序員可以不寫。
        但是如果從新定義了一個有參數的構造器那麽默認的無參數的構造器就沒有了
    此時,程序員應該將無參數的構造器自己定義出來。

10.static關鍵字 static修飾成員變量:那麽這個成員變量就是靜態成員變量,也就屬於類的成員變量。 static修飾方法:那麽這個方法就是靜態方法,也就屬於類的方法。

沒有static修飾的成員變量,那麽這個成員變量就是實例成員變量,屬於對象(實例)的成員變量
  沒有static修飾的方法,那麽這個方法就是實例方法,屬於對象(實例)的方法。

  補充:靜態的成員變量和靜態的方法其實通過對象也可以調用,但是不推薦
            非靜態的成員變量以及方法只能通過對象來調用,不能通過類來調用

11.成員變量的訪問 如果成員變量是被static修飾的,可以直接通過類來訪問。 類名.靜態成員變量名稱

如果成員變量是沒有被static修飾的,必須先有對象才可以訪問該成員變量。
類名 對象 = new 構造器;
對象.實例成員變量

註意:1.對於靜態成員變量,應該直接用類名來調用。
2.對象也可以訪問靜態的成員變量但是強烈不推薦使用對象來訪問靜態成員變量
--- 如果遇到面試題使用對象訪問靜態成員變量將對象換成類來解答。
3.類是絕對不能直接訪問實例成員變量的,實例成員變量必須先通過構造器創建對象再通過對象來訪問。
4.靜態成員變量只會與類同時加載一次

         實例成員變量(沒有用static修飾的成員變量),每次創建新的對象的時候,都會“復制”一份給這個對象。

12.調用方法 1.靜態方法(有static修飾的方法) 調用格式:[返回類型 變量 = ] 類名.方法名(參數值); 當就在這個靜態方法所在的類中調用次靜態方法的時候,可以省略類名調用。 因為一旦不是用對象調用那麽就是靜態方法,JVM會自動幫你加上當前類名去調用。

2.實例方法(沒有static修飾的方法)
創建對象:類名 對象變量 = new 構造器;
調用格式:[返回類型 變量 = ] 對象變量.方法名(參數值);
13.this關鍵字 this:當前對象 this在實例方法中的時候:哪個對象調用這個方法,this就代表哪個對象。 this在方法中一般用於很方便的操作當前調用此方法的對象。

this在構造器中的時候:this就代表正在創建的那個對象
this在構造器中一般用於對當前創建的對象,進行初始值的設置。

   this是代表對象的,而靜態方法被類直接調用.所以this不能出現在靜態方法中。

14.方法的重載

在同一個類中,方法名稱相同,形參列表不同就是方法的重載。

註意事項:
1.形參列表相同,形參變量不同不算重載

   2.形參列表相同,返回值不同不算重載

   3.調用重載的方法,只能識別一個就算重載。

15.變量 類變量(有static) ↗ 成員變量(定義在類中、保存堆中)
↗ ↘ 實例變量(無static) 變量 形參 ↘ ↗
局部變量(定義在方法中、保存棧中)→ 方法中定義的局部變量 ↘ 代碼塊定義的局部變量

註意:
1.成員變量可以不用定義初始值.初始值如果不申明就會采用默認的初始值
所有的數值型都是:0 或者 0.0 字符型式空格符
boolean類型的默認值false , 引用類型都是null

  2.成員變量可以在當前類中的任何地方訪問。
  3.靜態成員變量與類同時加載一次,只會加載一次。實例成員變量跟對象有關,每次創建
  對象都會為對象分配實例變量

靜態成員變量生命周期是從:類開始加載執行到類執行完成才會釋放。
實例成員變量:對象如果存在實例變量就存在。
16.代碼塊 實例代碼塊 實例代碼塊 // 實例代碼塊 { // 執行代碼 int a = 10 ; // 局部變量
int b = 11 ; System.out.println("-----------實例代碼塊----------------"+(a+b)); }

每次創建一個對象都會執行一次實例代碼塊
實際上底層是將實例化代碼塊中的代碼依次復制到每一個構造器中了,所以每次創建對象都會執行一次實例代碼塊中的代碼。
一般可以將構造器中相同的代碼提到一個實例化代碼塊中:這樣可以提高代碼的復用。
靜態代碼塊
// 靜態代碼塊 :類一加載就會立即執行靜態代碼塊。類加載一次,所以靜態代碼塊只會執行一次。
// 優先執行
static{
// 執行代碼
int a = 10 ; // 局部變量
int b = 1 ;
System.out.println("-------------static代碼塊----------------"+(a+b));
}
17.包 包的作用:

為了區別類,一般要使當前定義的類在全世界是唯一的。

為了當命令相同的java文件名的時候不至於沖突,這個時候就需要引入包。

不同的類可以擁有不同的包。

包:可以用於項目分層設計。
包名稱的來源: 公司域名(http://www.fkjava.org) ---- 域名的倒寫作為包 -----> org.fkjava.項目名稱

給類定義包:
格式: package 包名稱 ;
一般放在類文件的第一行。

註意: 1.如果一個類指定了包, 那麽也應該將類文件放到當前包下面編輯,編譯以後的

         class文件是一定要放到對應包下面。

           2.一旦類申明了包,那麽調用類的時候的完整格式應該是
                  類的全限名:包名稱.類名

方便的使用類:導包 import 包名稱.類名稱; 接下來就可以直接使用類。 import 包名稱.*; 就可以導入包下所有的類。

註意點: 1個類只能定義一個包 package 包名;
package 包名; 0~1

1個類可以導入很多的包
import 包名; 0~N ;

java.lang下的類不用導包
18.封裝、繼承、多態 面向對象的3大特征: 封裝、繼承、多態

--- 封裝:

類的設計:要把該隱藏的部分隱藏起來;要把用戶操作接口暴露出來。 ——封裝
合理隱藏、合理暴露。

一般來說:成員變量隱藏(有些常量也會暴露);方法暴露(有些特殊工具方法也會隱藏)

Java是提供了3個修飾符(4個權限)來控制隱藏和暴露(封裝)

private :它修飾的方法、成員變量只能在該類裏中被訪問。 徹底隱藏
不寫 :它修飾的方法、成員變量只能在該類、該類所在同一個包中被訪問。 部分隱藏、包訪問權限
protected :它修飾的方法、成員變量可以在該類、該類所在同一個包、該類子類中被訪問。 部分暴露、子類訪問權限
public :它修飾的方法、成員變量可以任意地方被訪問。 徹底暴露、公開權限

                 private       不寫          protected        public

當前類 √ √ √ √
同一個包 × √ √ √
當前類的子類 × × √ √
任意地方 × × × √

註意:
一般來說:成員變量應該隱藏(有些常量也會暴露);方法應該暴露(有些特殊工具方法也會隱藏)

    一般對成員變量進行隱藏, 但是會提供一套getter和setter方法來操作成員變量使其合理暴露。

-- 繼承:

代碼復用的一種方式。

 People                      Student  / Teacher

父類(超類、基類):大類; 子類(派生類):小類

  1. 語法格式:
    類 extends 類(只能有一個)
    一個類可以擁有多個子類或者沒有子類。一個類只能繼承一個父類
    java是單繼承:一個類只能繼承一個直接父類。

    繼承父類以後就可以獲得父類的所有成員變量和方法。
    子類只是擁有了父類的成員變量和方法,但是依然只能訪問有修飾權限的成員變量或者方法
    有時候父類的方法會申明成protected,protected修飾的成員子類可以直接訪問。

    一般來說子類是優於父類的,因為子類不僅獲得父類的成員變量和方法,而且子類自己還可以擴展。
    a. 1.概念子類繼承父類獲取父類的成員變量和方法

    2.java是單繼承的,一個類只能繼承一個直接父類。

    註意: 當一個沒有繼承另一個類的時候默認就會繼承一個Object類,但是可以省略寫繼承Object,默認會加上去。
    當一個類繼承了其他類它就不直接繼承Object但是一定會間接繼承了Object
    Object是一切的類的直接父類或者一定是間接父類.

    類的修結構:[修飾符] class <類名稱> [extends Object] {

        }

    方法重載(在同一個類中): 兩同一不同 同一個類,方法名相同 形參不同

方法重寫(子類對父類中的方法進行重寫): 兩同兩小一大

b. 方法重寫

@Override
方法重寫:子類認為從父類那裏繼承得到的方法不適合時或者認為不滿足自己的需求,
子類可以重寫父類的方法。一般重寫的實例方法,靜態方法沒有重寫的概念

所謂重寫,就是子類重新定義從父類得到的方法。

         方法重寫:2同2小1大。
           2同:方法名要相同,形參列表相同。
           2小:返回值類型要相同或更小(子類)相同類型 是繼承關系中的大小;
                   聲明拋出的異常相同或更小;
           1大:方法的訪問權限相同或更大。

     可以通過@Override來標記次方法一定需要是重寫的方法,如果不是重寫的就會報錯

不加@Override:方法有可能不是重寫的也可能是重寫的方法
              如果是重寫的方法必須合法,如果不是重寫的方法
               就是一個普通的方法

    所以建議子類在重寫父類的方法的時候應該加上@Override 。

    方法重寫與方法重載: 
     不同點: 
          方法重寫是在子類和父類之間的操作,重寫的方法在子類中。
      方法重載是在同一個類中

      方法重寫中重寫的方法必須與父類被重寫的方法的形參列表完全一致。
      方法重載重載的方法形參列表必須不一樣。

      方法重寫重寫的方法的訪問權限必須與父類相同或者更大
      方法重載的權限無所有。

      方法重寫的返回值類型必須與父類被重寫的方法的返回值類型相同或者更小
      方法重載無所謂返回值類型。

     相同點: 
          方法重寫的方法名必須與父類被重寫的方法的方法名稱相同
          重載的方法的方法名稱也是一樣必須相同

c、super:
super限定,用於訪問父類的成員(成員變量和方法)。
super.成員
super不能直接出現在靜態方法中來訪問父類的成員
可以在子類的對象方法中通過super訪問父類的成員。
d. 子類調用父類的構造器

【死規則】: 子類構造器一定會調用父類的構造器一次(有且僅有一次)

 - 子類構造器沒有顯式調用父類構造器,
   子類構造器會默認調用父類的無參數的構造器。

子類構造器之所以一定會調用父類的構造器是因為子類構造器中
存在一個super()調用:這個默認的super()調用會先調用父類的無參數構造器。

 - 子類構造器顯式用super調用來調用父類指定的構造器。
    super調用: super(參數)
    super調用 - 調用父類的構造器。只能在構造器的第一行。
    super(參數)  - 到底調用哪個構造器,取決你傳入的參數
    super()調用  this()調用不允許同時出現:因為this()和super()都只能放在第一行。

--- 多態

多態:多個相同類型的變量,調用同一個方法,表現出多種不同的行為特征,這就叫多態。

在繼承關系中也存在類型轉換.
子類是小類 父類是大類
子類可以自動轉換到父類:向上轉型

多態的原因:變量在調用方法的時候,實際上是找到變量真正指向的對象所擁有的該方法來執行。

繼承中的類型轉換:
子類是小類 父類是大類
子類可以自動轉換到父類:向上轉型
父類轉換到子類 : 需要強轉,而且執行的時候必須是同一個對象才可以強轉成功

java的類型分為編譯時類型和運行時類型:
編譯時類型: 只是在寫代碼到javac編譯的這個過程中的類型。
運行時類型: 在java命令執行的時候,真正指向的對象類型。

    父類轉換到子類 : 需要強轉,編譯時的時候是不會報錯的。
       但是在運行的時候,強轉以後的實際的對象與對應變量類型必須一致。
       否則會出現很經典的錯誤:ClassCastException(類轉換異常)

19.垃圾回收機制 java會自動回收沒有被引用的對象 ,不需要程序員去維護垃圾的回收。 20.final關鍵字 修飾符: 不寫 , private,public protected , static | final 類只能用public,final或者不寫。

final可以修飾變量(成員變量和局部變量)、方法、類。

【總規則】:final可以修飾變量:表示該變量被賦初始值之後,該變量不能被重新賦值
final修飾的變量只能賦值一次

final修飾的成員變量必須賦值,有且只能賦值一次!!!

▲ final修飾的成員變量:final修飾成員變量,必須有程序員顯式指定初始值。

final修飾的實例變量,一共可在3個地方指定初始值(只能指定一次):
 A - 定義時指定初始值。
 B - 在實例初始化塊中指定初始值。 {  }
 C - 在構造器中指定。如果在構造器中為final實例變量指定初始值,必須每個構造器中都要指定。
 表面上看,有3個地方,其實最終都會還原到構造器中執行。

--- 對象的final修飾的成員變量只能賦值一次

final修飾static的靜態變量,一共可在2個地方指定初始值(只能指定一次):

 A - 定義時指定初始值。
 B - 在類初始化塊中指定初始值。   static{   }

▲ final修飾的局部變量

不管是否有final修飾,在使用之前一定要給初始化值。

final修飾局部變量之後,final局部變量只能被賦值一次。

final變量,用於保護該變量的值,無論程序如何改變,該變量始終都是最初的值,永遠只能賦值一次。
▲ final修飾方法

表明該方法不能被重寫。@Override
重寫規則:2同2小1大。

final方法,用於保護該方法,防止被子類去重寫(覆蓋)

private與final同時修飾方法完全沒有意義的,但Java編譯器卻允許你這麽幹,這就是當年Java設計者留下的缺陷。
▲ final修飾類:

表明該類不能被繼承。

final類,用於保護該類,防止用於去派生子類。

Java的String、System、Math等大量的類都是final類。
反過來,如果給Object類加上final,整個Java體系就崩塌了。
21.toString 和equals(Object object)方法 一切類都是Object的子類 , toString()方法和equals(Object obj) 方法是Object類中的方法 所以所有的類都擁有了toString()方法和equals(Object obj) 方法 。

1.toString()方法

返回該對象的字符串表示,就是返回該對象的 名稱@hashcode 值。

直接輸出對象實際上是對象調用了toString()方法來打出對象的值:對象類名@hashcode hashcode相當於對象在內存中的地址
但是toString()可以省略。

toString()方法是Object的如果不重寫toString()方法,那麽是直接調用Object的toString()打出對象地址。
toString()方法存在的意義就是為了被子類重寫。
重寫出來一般用於打出對象的具體內容,如下:
@Override
br/>如果不重寫toString()方法,那麽是直接調用Object的toString()打出對象地址。
toString()方法存在的意義就是為了被子類重寫。
重寫出來一般用於打出對象的具體內容,如下:
@Override
// 可以打出對象的內容
return "User[name="+this.name+",age="+this.age+",passWord="+this.passWord+"]";

   那麽以後再輸出對象的時候,對象就會調用自己重寫的toString()方法來打出自己的內容

當然,toString()的調用默認可以省略不寫,會自動調用。

  1. equals(Object obj)方法

    == :在引用類型中:如果用來判斷兩個變量是否==,那麽這兩個變量指向的必須是同一個對象才算相等。
    如果指向的是不同的對象就不相等。

    equals:Object提供的equals方法的默認的作用就和==的效果是一樣的:用來判斷兩個對象是否相等
    必須是同一個對象才是true。

    equals存在的意義就是為了讓子類來重寫的。
    重寫以後可以自己制定對象的比較規則,從而使對象之間的比較判斷規則更加貼切的滿足業務需求。

    intanceof格式:用來判斷對象是否屬於某個類型
    對象 instanceof 類型 : 判斷對象是否是這個類型的對象。
    22.abstract abstract :抽象(抽象類、抽象方法)

修飾符(訪問權限修飾符):不寫,public,private,protected
靜態修飾符: static
保護修飾符: final

備註:非抽象類中不能定義抽象方法
抽象類中可以定義抽象方法,不寫抽象方法也可以
抽象類主要用於被繼承,因為抽象不能用於創建對象

abstract只能修飾類或方法。抽象類、抽象方法。
abstract與final是互斥:兩個不能同時修飾一個成員:
-- abstract修飾類和方法就是為了被繼承和重寫
-- final修飾類和方法 就是為了避免被繼承以及被重寫。

▲ 抽象方法:
格式:[修飾符] abstract 返回值 方法名(形參列表);

- 抽象方法不能定義方法體。
- 抽象方法必須使用abstract修飾

 註意:
 如果一個類擁有了抽象方法,這個類就必須定義成抽象類

抽象類就相當於一個模板,就是為了被繼承!!!

▲ 抽象類的特征: 有得有失。
除了這4個字之外,抽象類與普通類完全一樣的。
有得:抽象類得到新功能:可以擁有抽象方法。
有失:抽象類失去了:創建對象的能力。

▲ 抽象類的作用:

  • 被繼承
  • 定義變量
  • 調用類方法或訪問類變量。
  • 派生子類 - 要求抽象類必須有構造器。

    抽象類相當於定義一個“模板”,用於被子類去繼承。

一個類如果繼承了抽象類 如果這個類不處理繼承的抽象方法 那麽他自己也必須成為抽象類
一個類如果繼承了抽象類 如果希望成為實現類 那麽他就必須重寫抽象類中所有的抽象方法

子類繼承抽象父類,要麽子類重寫父類所有的抽象方法;
                 要麽子類也只能是抽象的。

抽象類的意義:抽象父類它只定義一些模板,這些模板相當於是子類一般都會有的
           但是抽象類它不清楚具體的行為是什麽樣子,只是設計了這樣一個模板。
       然後交給子類去繼承,子類拿到模板去豐富自己的行為

抽象類在編程中的好處: 模板集中管理,提高代碼的復用

模板模式。

23.接口(interface) 接口和抽象類都是一種特殊的類。

接口 : 相當於一種徹底抽象的類。

▲ 接口的語法:

[修飾符] interface <接口名> extends 父接口1,父借口2,......
{
// 0到多個常量定義。 不管你寫還是不寫,都有public static final修飾。
// 0到多個抽象方法定義、Java 8支持default、static方法(都可有方法體)定義
// 0到多個內部類等

}

▲ implements
接口是用來被實現的:一個類可以通過implements來實現接口
當一個類實現了某個接口就必須將接口中的抽象方法全部重寫
接口中的抽象方法可以只定義方法簽名,也可以使用abstract修飾

一個類只能有一個直接父類,但是可以實現多個接口
24.內部類 Java類的5大成分: 成員變量、方法、構造器、代碼塊、內部類

內部類:直接放在另一個類的類體中定義。
內部類可以提供更加好的封裝。

外部類(宿主類)
內部類(嵌套類、寄生類)

為什麽要定義內部類?內部類的便捷之處?

1. 內部類可以提供更好的封裝。
   內部類在外部類中可使用private、protected、public修飾,因此可以更好地進行封裝。

2. 內部類可以直接訪問外部類的成員,即使是外部類的private成員。
   靜態內部類(類成員)不允許直接訪問外部類的實例成員。

   當內部類的實例變量名與外部類的實例變量名沖突時。
   要顯式添加   外部類.this. 來限定訪問外部類的實例變量

★ 內部類與外部類的語法上區別:

  • 外部類只能使用 ,不寫,public、final|abstract。
    內部類可以使用private|protected|public、static、final|abstract修飾,

  • 非靜態內部類不允許擁有靜態成員,除非靜態成員變量,且使用final修飾,且指定了初始值。

  • 靜態內部類不允許直接訪問外部類的實例成員

▲ 使用靜態內部類

    靜態內部類的實例,必須寄生在外部類的類本身裏 
    在外部類以外的地方使用靜態內部類:
    外部類.內部類  —— 相當於外部類是內部類的一個包名。
再通過內部類對象就可以操作內部類的成員。

▲ 使用非靜態內部類 - 【難理解,僅供參考】

    【總原則】:非靜態內部類的實例,必須寄生在外部類的實例裏 
                ——如果沒有外部類的實例,不可能有非靜態內部類實例。

    ◆ 使用非靜態內部類定義變量:
        外部類.內部類 變量名;

    ◆ 使用非靜態內部類創建實例
        宿主.new 非靜態內部類構造器();

匿名內部類 : 針對於接口和抽象類

格式:直接在類中
 new 接口|抽象類(){
// 必須重寫所有的抽象方法
 }

匿名內部類不能復用。
 匿名內部類必須重寫所有的抽象方法

25.Lambda表達式 java8以後的新技術:“Lambda 表達式”(lambda expression)是一個匿名函數

就是可以以一種簡化的方式來創建匿名內部類

函數式接口中只能定義一個抽象方法!
接口類型 接口=()->{
}

函數式接口可以使用註解:@FunctionalInterface 來標記接口
一旦這個接口有多個抽象方法編譯就報錯。
26.正則表達式 正則表達式:用於校驗數據的格式是否正確

// 定義一個正則表達式
String regex = "[abc中]";
String regex1 = "[^abc中]";
String regex2 = "[a-z]";
String regex3 = "[A-Za-z3-9]";
String regex4 = "[9[0-7]]";
String regex5 = "ab";
String regex6 = "."; // 任何字符
//matches(String regex)
// 告知此字符串是否匹配給定的正則表達式。
System.out.println("國".matches(regex));
System.out.println("中".matches(regex1));
System.out.println("ab".matches(regex2));
System.out.println("a".matches(regex2));
System.out.println("3".matches(regex3));
System.out.println("8".matches(regex4));
System.out.println("ab".matches(regex5)); // true 一定要一樣類似於equals判斷
System.out.println("在".matches(regex6));
System.out.println("9".matches("\d"));

System.out.println("到".matches("\\D"));
System.out.println(" ".matches("\\s")); // 空格字符  true
System.out.println(" ".matches("\\S")); // 非空格字符 false
System.out.println("$".matches("\\w")); // [a-zA-Z_0-9] 
System.out.println("在".matches("\\W")); 

System.out.println("aabcbcbca".matches("[abc]*")); 
System.out.println("042424".matches("[0-9]+")); 
System.out.println("af43".matches("\\w{4}")); 
System.out.println("admi2n".matches("\\w{6,10}"));

String str = "(總部)地址dsfdvvv:北京市東城區東[email protected]中街32號樓7層(東環廣場對面)郵編:100027 " + "電話:1010-3721,400-610-3721 ,傳真:010-64170018 手機號碼:13360026135,15800000653 郵件:[email protected](網絡部)" + "[email protected] (客服部)[email protected] (市場部)" ;

// 定義一個電話號碼正則表達式
String telRegex = "1[34578]\d{9}";
String emailRegex = "\w{1,20}@\w{2,10}(\.\w{2,10}){1,2}"; // java

// 1.將正則表達式編譯成java代碼中的對象Pattern
Pattern p = Pattern.compile(emailRegex);
// 2.再通過正則表達式獲取一個匹配器
Matcher m = p.matcher(str);
// 3.開始拿著匹配器去內容中匹配出滿足正則表達式條件的內容
while(m.find()){
     System.out.println(m.group()) ; // 拿到正則表達式匹配的完整內容
     //System.out.println(m.group(1)); //    拿到正則表達式的第一個括號匹配對應的內容
}

2 面向對象