乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      java面向?qū)ο蟾呒?jí)

       路人甲Java 2021-04-30

      1、類變量(靜態(tài)類變量)
      1、為什么要有靜態(tài)類變量?
      
      引出: 
      過年,公司發(fā)過年禮品,假設(shè)我們有一個(gè)禮品類Gift,有一個(gè)發(fā)放禮品的類方法receive(),我想知道當(dāng)前有多少個(gè)員工領(lǐng)取禮品,怎么辦?
      
      解決:
      1、在類中定義一個(gè)屬性count,然后在receive()里每調(diào)用該方法進(jìn)行conut++?
      2、在main方法定義一個(gè)count局部變量,每調(diào)用一次receive()進(jìn)行count++?
      3、在類中定義一個(gè)靜態(tài)的類變量,在方法receive()中進(jìn)行count++?
      
      答案:選擇3!第一種不管領(lǐng)取了多少禮品,每個(gè)對(duì)象中的count屬性值都是1;第二種可以是可以,但不符合oop的思想,如果需要在別的地方用到該count值,沒辦法調(diào)用啊;第三種,靜態(tài)類變量多個(gè)對(duì)象共享該變量,不管是用那個(gè)對(duì)象獲取的count值,都是最新的且一致的!
      
      #測試代碼:
      public class StaticDemo {
          public static void main(String[] args) {
              Gift gift = new Gift("張三");
              Gift gift1 = new Gift("李四");
      
              gift.receive();
              System.out.println("當(dāng)前有"+Gift.count+"個(gè)員工領(lǐng)取了禮品"+"  名字分別為:"+ Gift.str);
      
              gift1.receive();
              System.out.println("當(dāng)前有"+gift1.count+"個(gè)員工領(lǐng)取了禮品"+"  名字分別為:"+ Gift.str);
          }
      }
      //禮品類
      class Gift{
          private String name;
          protected static int count;
          public static String str="";
      
          public Gift(String name) {
              this.name = name;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          //發(fā)放禮品
          public void receive(){
              giftEliminate();
              count++;
              str = str.concat(getName());
          }
      
          //當(dāng)領(lǐng)取人數(shù)大于5個(gè)我就調(diào)用該方法將count清零;
          public void giftEliminate(){
              if (count>5){
                  Gift.count = 0;
              }
          }
      }
      
      輸出:
      當(dāng)前有1個(gè)員工領(lǐng)取了禮品  名字分別為:張三
      當(dāng)前有2個(gè)員工領(lǐng)取了禮品  名字分別為:張三李四
      
      小結(jié)(什么時(shí)候使用類變量?):
      1、靜態(tài)類變量的作用就是存儲(chǔ)一些獨(dú)立于對(duì)象的數(shù)據(jù),但各對(duì)象又能共享該變量值
      
      
      
      2、如何定義和使用靜態(tài)類變量?
      定義:
      1、static public int count  
      2、public static int count (推薦使用)
      #從上面代碼可以看出,在普通屬性上聲明一個(gè)static關(guān)鍵字,靜態(tài)類方法也是如此
      
      使用:
      1、使用類名.變量名(推薦使用) Gift.count
      2、對(duì)象名.變量名 gift1.count
      
      3、類變量于實(shí)例變量(普通類屬性)的區(qū)別?
      1、類變量屬于類,但被所有對(duì)象共享
      2、實(shí)例變量只屬于這一個(gè)對(duì)象,獨(dú)立不被共享
      
      
      
      4 小結(jié):
      類變量:
      1、使用關(guān)鍵字static聲明定義,推薦定義格式: 修飾符 static 數(shù)據(jù)類型 變量名
              2、使用類名.變量名調(diào)用該類變量
              3、被所有對(duì)象共享變量值
              
      實(shí)例變量:
      1、定義:修飾符 數(shù)據(jù)類型 變量名
      2、使用對(duì)象名.變量名調(diào)用該變量
      3、只屬于該對(duì)象本身,不被共享
      
      2、靜態(tài)方法
      1、為什么要有靜態(tài)方法?
       應(yīng)用:
       當(dāng)我們要寫一個(gè)方法操作一些跟對(duì)象無關(guān)的數(shù)據(jù)時(shí),可以使用靜態(tài)方法。
        
      
      2、靜態(tài)方法的定義和使用
      定義:
      1、public static void print(){}
      2、static void print(){}
      修飾符 static 返回?cái)?shù)據(jù)類型 方法名(){}
      
      #注意:因?yàn)樾揎椃椒ǖ男揎椃挥衟ublic 或 默認(rèn)(不寫)
      
      使用:
       1、類名.方法名() (推薦使用)
       
       2、對(duì)象名.方法名()
       
       
       
       
      代碼:
      
      public class StaticDemo {
          public static void main(String[] args) {
              Student student = new Student("張三");
              Student student1 = new Student("李四");
      
              Student.count_study_money(3000);
              Student.count_study_money(5000);
      
              System.out.println("當(dāng)前學(xué)費(fèi)共交了"+Student.get_study_money()+"元");
              student.print();
          }
      }
      
      class Student{
          public String name;
          private static double study_money;
          static String str="";
      
          public Student(String name){
              super();
              this.name = name;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          //計(jì)算學(xué)費(fèi)
          public static void count_study_money(double study_money){
              //Student.study_money = Student.study_money + study_money;
              Student.study_money += study_money;
          }
      
          //返回學(xué)費(fèi)
          public static double get_study_money(){
      
              return Student.study_money;
          }
          
          public void print(){
              System.out.println(get_study_money());//非靜態(tài)方法中調(diào)用靜態(tài)方法
              System.out.println(name);//非靜態(tài)方法中調(diào)用非靜態(tài)變量
              System.out.println(str);//非靜態(tài)方法中調(diào)用靜態(tài)變量
          }
      }
      
      輸出:
      當(dāng)前學(xué)費(fèi)共交了8000.0元
      8000.0
      張三
      
      
      
      3、使用類方法時(shí),有哪些要注意的細(xì)節(jié)?
      
      1、類方法中不能使用this和super與對(duì)象相關(guān)的關(guān)鍵字。 因?yàn)閠his代表調(diào)用者當(dāng)前對(duì)象本身,而靜態(tài)方法執(zhí)行是無需實(shí)例化對(duì)象,那這個(gè)this就是空,所以靜態(tài)方法中不能用this
      
      2、類方法和類變量調(diào)用跟對(duì)象是否創(chuàng)建無關(guān),調(diào)用時(shí)都是通過類名.類變量/類方法()調(diào)用
      
      3、而對(duì)象變量和對(duì)象方法與實(shí)例對(duì)象有關(guān),調(diào)用對(duì)象方法和對(duì)象變量時(shí)只能用對(duì)象名.變量 或 對(duì)象名.方法名(),不能使用類名.方法和變量!
      
      4、靜態(tài)(類)方法中只能調(diào)用靜態(tài)(類)變量和靜態(tài)方法,無法使用非靜態(tài)變量和非靜態(tài)方法
      
      5、非靜態(tài)方法可以調(diào)用非靜態(tài)變量、非靜態(tài)方法、靜態(tài)方法、靜態(tài)變量
      
      

      i

      3、Main()方法
      public static void main(String[] args){}
      
      1、為什么main()方法要這樣寫?
      # 因?yàn)橛辛藀ublic權(quán)限,所以jvm才能調(diào)用main;
        因?yàn)橛辛藄tatic,所以調(diào)用mian()方法時(shí)不需要有對(duì)象創(chuàng)建; 
        因?yàn)橛辛薙tring[] args字符串?dāng)?shù)組,所以運(yùn)行main里面的程序時(shí),可以用字符串?dāng)?shù)組去存儲(chǔ)中轉(zhuǎn)所需的參數(shù)!
      
      4、代碼塊
      1、代碼塊的定義
      1、普通代碼塊
      格式:{代碼體}
      
      2、靜態(tài)代碼塊
      static{代碼體}
      
      
      2、普通代碼與靜態(tài)代碼塊的使用區(qū)別
      
      普通代碼塊:
      1、是對(duì)對(duì)象進(jìn)行初始化。每創(chuàng)建一次對(duì)象就執(zhí)行一次
      
      靜態(tài)代碼塊:
      1、是對(duì)類進(jìn)行初始化。隨著類被加載的時(shí)候就執(zhí)行了,且只會(huì)執(zhí)行一次(不管new幾個(gè)對(duì)象)
      
      
      #代碼驗(yàn)證:
      
      //午餐類
      class Lunch{
          public static double price=20;
      
          //普通代碼塊
          {
              System.out.println("普通代碼塊:先煮飯,洗菜,炒菜");
          }
          //靜態(tài)代碼塊
          static {
              System.out.println("靜態(tài)代碼塊:先煮飯,洗菜,炒菜");
          }
      
          //無參構(gòu)造器
          public Lunch() {
              System.out.println("這是無參構(gòu)造器");
          }
      
          //靜態(tài)方法
          public static void makeLunch(){
              System.out.println("這是一個(gè)靜態(tài)方法");
          }
      }
      
      public class codeBlock {
          public static void main(String[] args) {
              Lunch lunch = new Lunch();
              Lunch lunch1 = new Lunch();
              Lunch lunch2 = new Lunch();
              Lunch.makeLunch();
              System.out.println(Lunch.price);
          }
      }
      
      
      輸出:
      靜態(tài)代碼塊:先煮飯,洗菜,炒菜
      普通代碼塊:先煮飯,洗菜,炒菜
      這是無參構(gòu)造器
      普通代碼塊:先煮飯,洗菜,炒菜
      這是無參構(gòu)造器
      普通代碼塊:先煮飯,洗菜,炒菜
      這是無參構(gòu)造器
      這是一個(gè)靜態(tài)方法
      20.0
      
      說明:
      1、執(zhí)行順序: 靜態(tài)代碼塊——》普通代碼塊——》構(gòu)造器
      2、執(zhí)行次數(shù):靜態(tài)代碼塊只執(zhí)行一次,普通代碼塊執(zhí)行次數(shù)跟對(duì)象創(chuàng)建次數(shù)一樣
      3、靜態(tài)方法調(diào)用一次就執(zhí)行一次
      
      
      
      3、觸發(fā)類加載的幾種情況(靜態(tài)代碼塊)
      1、創(chuàng)建對(duì)象實(shí)例時(shí)
      2、當(dāng)創(chuàng)建子類對(duì)象實(shí)例時(shí),先加載父類,再加載子類
      3、使用類的靜態(tài)成員(靜態(tài)屬性、靜態(tài)方法)
      4、還有一種是反射( 我還沒學(xué)>_<...)
      
      #代碼驗(yàn)證:
      
      public class codeBlock02 {
          public static void main(String[] args) {
              new CC();
              //1、創(chuàng)建對(duì)象實(shí)例時(shí)會(huì)觸發(fā)類加載,執(zhí)行靜態(tài)代碼塊。
              //2、當(dāng)創(chuàng)建子類對(duì)象實(shí)例時(shí),當(dāng)前類CC向上的所有父類AA、BB類都會(huì)觸發(fā)類加載,從而執(zhí)行對(duì)應(yīng)類的靜態(tài)代碼塊
           
      
              //System.out.println(CC.str);
              //1、當(dāng)調(diào)用靜態(tài)成員(靜態(tài)方法和變量)時(shí),會(huì)觸發(fā)類加載,執(zhí)行靜態(tài)代碼塊內(nèi)容
          }
      }
      
      class AA{
          //普通代碼塊
          {
              System.out.println("普通代碼塊AA");
          }
          //靜態(tài)代碼塊
          static {
              System.out.println("靜態(tài)代碼塊AA");
          }
      }
      
      class BB extends AA{
          //普通代碼塊
          {
              System.out.println("普通代碼塊BB");
          }
          //靜態(tài)代碼塊
          static {
              System.out.println("靜態(tài)代碼塊BB");
          }
      }
      
      class CC extends BB{
          public static String str="這是靜態(tài)變量";
          //普通代碼塊
          {
              System.out.println("普通代碼塊CC");
          }
          //靜態(tài)代碼塊
          static {
              System.out.println("靜態(tài)代碼塊CC");
          }
      
          public CC() {
              System.out.println("這是CC的無參構(gòu)造器");
          }
      }
      
      執(zhí)行new CC()輸出:
      靜態(tài)代碼塊AA
      靜態(tài)代碼塊BB
      靜態(tài)代碼塊CC
      普通代碼塊AA
      普通代碼塊BB
      普通代碼塊CC
      這是CC的無參構(gòu)造器
      
      執(zhí)行System.out.println(CC.str)輸出:
      靜態(tài)代碼塊AA
      靜態(tài)代碼塊BB
      靜態(tài)代碼塊CC
      這是靜態(tài)變量
      
      說明:上面結(jié)論是正確的!
      
      
      
      4、創(chuàng)建一個(gè)類對(duì)象時(shí),類中靜態(tài)代碼塊、靜態(tài)變量、普通代碼塊、普通變量、構(gòu)造器的執(zhí)行順序是什么?
      
      上代碼測試:
      
      public class codeBlock02 {
          public static void main(String[] args) {
              AA aa = new AA();
          }
      }
      
      class AA{
      
          //普通變量
          public int numb = getNumb();
      
          //靜態(tài)類變量
          public static String str=getStr();
      
          //普通方法
          public int getNumb(){
              System.out.println("getNumb被執(zhí)行了");
              return 10;
          }
      
          //靜態(tài)方法
          public static String getStr(){
              System.out.println("getStr()方法被執(zhí)行");
              return "類變量";
          }
      
          //構(gòu)造器
          public AA(){
          super();//當(dāng)有父類時(shí)會(huì)執(zhí)行,沒有不執(zhí)行    <1>
             <2>
              System.out.println("這是AA的無參構(gòu)造器"); <3>
          }
          // 在<2>這里我感覺隱藏了調(diào)用普通代碼塊的引用代碼,因?yàn)槊縩ew一個(gè)對(duì)象時(shí),執(zhí)行順序都是: <1> ---> <2> ---> <3>; 
          
      
          //普通代碼塊
          { System.out.println("普通代碼塊AA");}
                   
          //靜態(tài)代碼塊
          static {System.out.println("靜態(tài)代碼塊AA");}
      }
      
      //輸出:
      //    getStr()方法被執(zhí)行   ---》靜態(tài)類變量
      //    靜態(tài)代碼塊AA     ---》靜態(tài)代碼塊
      //    getNumb被執(zhí)行了    ---》普通類變量
      //    普通代碼塊AA---》普通代碼塊
      //    這是AA的無參構(gòu)造器  ---》構(gòu)造器
      
      
      說明什么?
      1、先執(zhí)行靜態(tài)static的靜態(tài)代碼塊或靜態(tài)類變量,這兩優(yōu)先級(jí)一樣,執(zhí)行順序就看定義的位置誰先誰后
      2、然后執(zhí)行普通代碼塊或普通類變量,這兩優(yōu)先級(jí)也一樣,執(zhí)行順序就看定義的位置誰先誰后
      3、最后執(zhí)行構(gòu)造器
      
      4、在構(gòu)造器中super()下面還隱藏了一段看不見的調(diào)用普通代碼塊的引用代碼
      
      
      
      5、小練習(xí)(代碼塊)
       #請(qǐng)問以下代碼輸出什么?
      
      public class codeBlock01 {
          public static void main(String[] args) {
              new B();
          }
      }
      
      class A{
          //靜態(tài)屬性
          public static int number_A = getA1();
      
          //靜態(tài)代碼塊
          static { System.out.println("A類靜態(tài)代碼塊");}
      
          //普通代碼塊
          {  System.out.println("A類普通代碼塊"); }
      
          //普通屬性
          public int age_A = getA2();
      
          //父類構(gòu)造方法
          public A(){
              System.out.println("打印A類構(gòu)造器");
          }
      
          public static int getA1(){
              System.out.println("調(diào)用了getA1方法");
              return 20;
          }
      
          public int getA2(){
              System.out.println("調(diào)用了getA2方法");
              return 31;
          }
      }
      class B extends A{
      
          //靜態(tài)代碼塊
          static { System.out.println("B類的靜態(tài)代碼塊"); }
      
          //靜態(tài)屬性
          public static String getStringB1 = getB1();
      
          //普通代碼塊
          { System.out.println("B類的普通代碼塊"); }
      
          //普通屬性
          public String getStringB2 = getB2();
      
          //子類構(gòu)造方法
          public B(){
              super();
              System.out.println("打印A類構(gòu)造器");
          }
      
          public static String getB1(){
              System.out.println("調(diào)用了getB1方法");
              return "B1";
          }
      
          public String getB2(){
              System.out.println("調(diào)用了getB2方法");
              return "B2";
          }
      }
      
      輸出:
      調(diào)用了getA1方法
      A類靜態(tài)代碼塊
      B類的靜態(tài)代碼塊
      調(diào)用了getB1方法
      A類普通代碼塊
      調(diào)用了getA2方法
      打印A類構(gòu)造器
      B類的普通代碼塊
      調(diào)用了getB2方法
      打印A類構(gòu)造器
      
      
      6、小練習(xí)
      以下程序會(huì)輸出?
      public class Test {
          static String s = "琳";
          static {
              String s = "麗";
              System.out.println(s);   // <1> 靜態(tài)代碼塊最先執(zhí)行,輸出麗
          }
          public static void main(String[] args) {
              new Son(s);  //把"琳"傳進(jìn)去
      
          }
      }
      
      class Father{
          static int m=100;
          public Father(){ m=999;} //父類的m=999,不改變靜態(tài)變量m的值
          static {
              m=10000;
              System.out.println("父類"+m);}  // <2> 輸出:父類10000
      }
      
      class Son extends Father{
          int m;
          { super.m=5;} //這里修改了父類屬性m=5
      
          static {
              System.out.println("static block");  //<3> 輸出:static block
          }
      
          public Son(String name){
              System.out.println(name); //<4> 輸出: "琳"
              System.out.println(m);<5> 輸出: 子類屬性沒有賦值,所以m=0;
              System.out.println(super.m); <6>輸出: 5
          }
      }
      
      最終輸出:麗,父類10000,static block,"琳",0,5
      
      5、單例模式
      # 使用靜態(tài)方法和靜態(tài)屬性實(shí)現(xiàn)單例模式
      # 單例模式特點(diǎn):一點(diǎn)創(chuàng)建了一個(gè)對(duì)象,之后就無法創(chuàng)建新對(duì)象,一個(gè)類只能有一個(gè)對(duì)象實(shí)例
      
      #思路
      1、限制創(chuàng)建對(duì)象
      2、判斷是否已經(jīng)存在一個(gè)對(duì)象實(shí)例
      
      
      代碼實(shí)現(xiàn):
      public class SingletonMode {
          public static void main(String[] args) {
              //固定式
              Singleton1 singleton1 = Singleton1.getSingleton();
              Singleton1 singleton2 = Singleton1.getSingleton();
              System.out.println(singleton1==singleton2);//返回true,說明成功了
      
              //靈活式
              Singleton2 singleton3 = Singleton2.getSingleton("小花");
              Singleton2 singleton4 = Singleton2.getSingleton("小梅");
              System.out.println(singleton3==singleton4);//返回true,說明成功了
      
              /*
              實(shí)現(xiàn)單例模式
              思路:
                  1、限制創(chuàng)建新對(duì)象
                  2、判斷該類中是否已經(jīng)存在一個(gè)對(duì)象實(shí)例
              */
          }
      }
      
      //實(shí)現(xiàn)一:固定式
      class Singleton1{  //缺點(diǎn)就是:這個(gè)name參數(shù)值在編寫時(shí)必須寫死,那有沒有自己傳參值來new一個(gè)呢,看下一個(gè)
      
          private String name;
          private static Singleton1 singleton = new Singleton1("小琳");
          //私有化構(gòu)造器
          private Singleton1(String name){
              super();
              this.name =name;
          }
          //提供一個(gè)static方法獲取對(duì)象
          public static Singleton1 getSingleton(){
              return singleton;
          }
      }
      
      //實(shí)現(xiàn)二:靈活式  可以自定義單例對(duì)象的數(shù)值
      class Singleton2{
          private String name;
          private static Singleton2 Singleton;
      
          //私有化構(gòu)造器
          private Singleton2(String name){
              super();
              this.name = name;
          }
          //提供一個(gè)判斷對(duì)象是否存在且可以返回對(duì)象的方法
          public static Singleton2 getSingleton(String name){
              //判斷當(dāng)前是否存在對(duì)象
              if (Singleton == null){
                  return Singleton = new Singleton2(name);
              }
              return Singleton;
          }
      }
      
      
      小結(jié)(固定式和靈活式的區(qū)別):
      
      對(duì)象創(chuàng)建時(shí)間上:
          固定式是在類加載時(shí)就創(chuàng)建了該對(duì)象,而靈活式要調(diào)用才會(huì)創(chuàng)建對(duì)象
          
          資源浪費(fèi)上:
          固定式有可能創(chuàng)建后就沒有用過所以存在浪費(fèi)資源的可能,而靈活式就不會(huì)有這情況
          
          靈活度上:
          固定式是在編寫代碼時(shí)對(duì)象就確定了,后續(xù)不能改變,而靈活式可以在第一次創(chuàng)建對(duì)象時(shí)選擇創(chuàng)建的對(duì)象值
          
          線程安全上:
          固定式是線程安全的,靈活式是線程不安全的!
      
      6、抽象類
      6.1、抽象類的介紹
      1、抽象類定義
      訪問修飾符 abstract 類名{ }//沒有類實(shí)現(xiàn) 
      
      2、抽象方法定義
      訪問修飾符 abstract 方法名(參數(shù)列表)//沒有方法體
      
      3、抽象類的價(jià)值更多的體現(xiàn)在設(shè)計(jì)層面,設(shè)計(jì)者設(shè)計(jì)好抽象類讓子類繼承并實(shí)現(xiàn)抽象類的功能,更多的是充當(dāng)一個(gè)模板的作用,應(yīng)用場景更多體現(xiàn)在設(shè)計(jì)模式和框架上!
      
      6.2、抽象類的特點(diǎn)
      1、抽象類不能被實(shí)例化創(chuàng)建
      
      2、抽象類中,可以有抽象方法,也可以沒有抽象方法
      
      3、一個(gè)方法一旦聲明了成抽象方法,該方法的類也必須聲明為抽象類!總結(jié):抽象類不一定有抽象方法,但有抽象方法的類一定是抽象類
      
      4、abstract只能修飾類和方法,不能修飾類屬性(只有抽象類和方法之說,沒有抽象屬性之說)
      
      5、普通類里可以有的抽象類都可以有(如靜態(tài)方法、靜態(tài)屬性、靜態(tài)代碼塊、普通代碼塊),普通類里沒有的抽象方法抽象類有!
      
      6、抽象方法沒有方法體
      
      7、如果一個(gè)類繼承了抽象類,那就必須實(shí)現(xiàn)該抽象類的所有抽象方法,除非把自己也聲明為抽象類!
      
      8、抽象方法不能使用private、final、static修飾。
      #因?yàn)槌橄蠓椒ǘx后必須實(shí)現(xiàn),而重寫也是一種實(shí)現(xiàn)的方式,private私有化不能被重寫,final不能被繼承也就無法重寫,static靜態(tài)化方法只跟類相關(guān),沒有對(duì)象去實(shí)現(xiàn)這個(gè)抽象方法,重寫是跟對(duì)象相關(guān)的!
      
      
      6.3、多態(tài)在抽象類的體現(xiàn)
      1、多態(tài)參數(shù): 
      [抽象父類的引用也可以指向繼承它的所有子類對(duì)象,所以可以使用抽象父類的引用作為形參去接收傳遞過來的所有子類對(duì)象參數(shù)] 什么意思?看下面代碼
      
      
      代碼:
      ----------------------------------------------------------------------------------------
      /*  驗(yàn)證:
          多態(tài)參數(shù):接收子類對(duì)象
          多態(tài)數(shù)組:存儲(chǔ)各個(gè)子類對(duì)象
       */
      
      //抽象父類-寵物類
      abstract class  Pets{
          private String name;
      
          public Pets(String name) {
              super();
              this.name = name;
              System.out.println(name);
          }
      }
      //寵物狗類
      class petsDog extends Pets{
          public petsDog(String name){
              super(name);
          }
      }
      //寵物貓類
      class petsCat extends Pets{
          public petsCat(String name){
              super(name);
          }
      }
      //測試類
      
      public class Abstract01 {
          public static void main(String[] args) {
              Pets cat = new petsCat("加菲貓");
              Pets dog = new petsDog("旺財(cái)");
              //抽象父類引用Pets可以作為形參接收petsCat("加菲貓")和petsDog("旺財(cái)")
              // 這兩個(gè)子類對(duì)象實(shí)例,就證明了抽象類也具有多態(tài)參數(shù)的特性
          }
      }
      
      輸出:
      加菲貓
      旺財(cái)
      
      
      2、多態(tài)數(shù)組:
      [抽象父類也可以存放所有繼承的子類對(duì)象]什么意思?看下面代碼
      
      代碼:
      
      /*  驗(yàn)證:
          多態(tài)參數(shù):接收子類對(duì)象
          多態(tài)數(shù)組:存儲(chǔ)各個(gè)子類對(duì)象
       */
      //抽象父類-寵物類
      abstract class  Pets{
          private String name;
      
          public Pets(String name) {
              super();
              this.name = name;
              System.out.println(name);
          }
      
          public String getName(){
              return name;
          }
      
          //定義一個(gè)公有的抽象方法play(),玩
          public abstract void play();
      }
      //寵物狗類
      class petsDog extends Pets{
          public petsDog(String name){
              super(name);
          }
      
          //重寫實(shí)現(xiàn)play()方法
          @Override
          public void play() {
              System.out.println(getName()+"可以拿來擼");
          }
      
          //狗特有行為:看大門
          public void guardHome(){
              System.out.println(getName()+"會(huì)幫主人看家");
          }
      }
      //寵物貓類
      class petsCat extends Pets{
          public petsCat(String name){
              super(name);
          }
          @Override
          public void play(){
              System.out.println(getName()+"可以拿來擼");
          }
          //貓?zhí)赜行袨?抓老鼠
          public void captureMouse(){
              System.out.println(getName()+"會(huì)抓老鼠");
          }
      }
      
      //測試類
      public class Abstract01 {
          public static void main(String[] args) {
              //在這里定義一個(gè)抽象父類Pets數(shù)組,去接收不同的子類對(duì)象
              Pets[] pets = new Pets[]{new petsCat("加菲貓"),new petsDog("旺財(cái)"),};
              //抽象父類引用pets去接收并存儲(chǔ) new petsCat("加菲貓") 和 new petsDog("旺財(cái)")子類對(duì)象,運(yùn)行時(shí)會(huì)進(jìn)行動(dòng)態(tài)綁定!
              new Abstract01().getObject(pets);
          }
      
          //定義一個(gè)判斷子類對(duì)象類型的方法,并打印出對(duì)象對(duì)應(yīng)的特有方法
          public void getObject(Pets[] abs){
              //使用instanceof進(jìn)行子類對(duì)象類型判斷
              for (Pets p:abs){
                  if (p instanceof petsCat){
                      ((petsCat)p).captureMouse();
                  }else { //因?yàn)槌橄蟾割悷o法被實(shí)例化,所以不可能會(huì)有父類的對(duì)象出現(xiàn),對(duì)象只可能兩種類型
                      ((petsDog) p).guardHome();
                  }
              }
          }
      }
      
      6.4、抽象類體現(xiàn)了模板設(shè)計(jì)模式
      1、抽象充當(dāng)了多個(gè)子類的通用模板,子類可以在繼承抽象類的基礎(chǔ)上進(jìn)行擴(kuò)展,但子類中還是保留一定的抽象父類的行為方法
      
      2、什么是模板設(shè)計(jì)模式?
      #當(dāng)有一部分功能是確定的,一部分功能是不確定的,可以用模板設(shè)計(jì)模式設(shè)計(jì)一個(gè)抽象父類,里面定義一個(gè)抽象方法,這個(gè)抽象方法做不確定功能,確定的功能在抽象父類寫一個(gè)方法實(shí)現(xiàn)好;然后讓子類繼承并實(shí)現(xiàn)這個(gè)功能不確定的抽象方法
      
      
      上代碼演示:
      3、需求:我想要一個(gè)抽象類,用于計(jì)算一個(gè)方法執(zhí)行的時(shí)間(什么方法不確定,但是用于計(jì)算時(shí)間的方法確定)
      
      //抽象計(jì)算類
      //抽象計(jì)算類
      abstract class Calculation{
          //抽象方法
          abstract public void Method();
      
          //計(jì)算耗時(shí)的方法
          public void consumeTime(){
              long start_time = System.currentTimeMillis();
              Method();
              long end_time = System.currentTimeMillis();
              System.out.println("該方法耗時(shí)為:"+(end_time-start_time));
          }
      }
      
      class Son1 extends Calculation{
          @Override
          public void Method(){
              String str = "";
              for (int i = 0; i < 100000; i++) {
                  str += "SB";
              }
          }
      }
      
      class Son2 extends Calculation{
          @Override
          public void Method(){
              StringBuffer str = new StringBuffer("");
              for (int i = 0; i < 100000; i++) {
                  str.append("SB");
              }
          }
      }
      
      class Son3 extends Calculation{
          @Override
          public void Method(){
              StringBuilder str = new StringBuilder("");
              for (int i = 0; i < 100000; i++) {
                  str.append("SB");
              }
          }
      }
      
      
      //測試類
      public class Template {
          public static void main(String[] args) {
              //實(shí)現(xiàn)一:
                  //new Son1().consumeTime();
                  //son1先找自己consumeTime方法,沒有就找父類consumeTime方法,
                  // 父類consumeTime根據(jù)動(dòng)態(tài)綁定調(diào)用自己的Method方法
                  //new Son2().consumeTime();
                  //new Son3().consumeTime();
      
              //實(shí)現(xiàn)二:
              Template.test(new Son1()); //調(diào)用靜態(tài)方法:類名.方法名
              new Template().test(new Son2());//調(diào)用靜態(tài)方法:對(duì)象.方法名
              test(new Son3()); //因?yàn)樵摲椒ㄔ谕愔?,直接方法?    }
      
          public static void test(Calculation c){
              c.consumeTime();
          }
      }
      
      輸出:
      該方法耗時(shí)為:12139
      該方法耗時(shí)為:3
      該方法耗時(shí)為:2
      //說明字符串拼接操作效率:StringBuilder > StringBuffer > String;
      
      
      7、接口
      1、接口介紹:
      就是把一些沒有實(shí)現(xiàn)的方法通過接口封裝到一起,當(dāng)哪個(gè)類需要使用到接口的方法的時(shí)候,該類根據(jù)需求再具體去實(shí)現(xiàn)接口里的方法
      
      接口定義格式:
      interface 接口名{
      屬性
      抽象方法(接口里的方法默認(rèn)是abstract抽象的)
      在jdk1.8后,接口里可以有 靜態(tài)方法 和 默認(rèn)方法的實(shí)現(xiàn)
      }
      
      實(shí)現(xiàn)接口格式:
      class 類名 implements 接口名{
      //可以有自己的屬性和方法,但是必須實(shí)現(xiàn)(重寫)接口的所有方法,可以跟接口隔離原則去優(yōu)化
      自己屬性
      自己方法
      必須實(shí)現(xiàn)接口的抽象方法
      }
      
      
      #栗子:
      
      //接口
      interface interfaceDemo{
          //接口里的屬性必須定義時(shí)給定初始值
          public String str="111"; 
          //等同public static final String str = "111"
      
          //靜態(tài)方法
          public static void print01(){
              System.out.println("靜態(tài)方法");
          }
      
          //默認(rèn)方法
          public default void pint02(){
              System.out.println("默認(rèn)方法");
          }
          
          //抽象方法
          void absMethod1();
          void absMethod2();
      }
      
      //測試類
      public class Interface02 {
          public static void main(String[] args) {
              //接口里的靜態(tài)方法直接用接口名調(diào)用,跟類的靜態(tài)方法調(diào)用一樣
              interfaceDemo.print01();
              //默認(rèn)方法接口自己無法使用接口名調(diào)用
              //interfaceDemo.print02();
      
          }
      }
      
      //普通類
      class Ordinary implements interfaceDemo{
          
          //實(shí)現(xiàn)一個(gè)抽象方法1還是報(bào)錯(cuò),接著實(shí)現(xiàn)方法2報(bào)錯(cuò),實(shí)現(xiàn)默認(rèn)方法后不報(bào)錯(cuò),說明要全部實(shí)現(xiàn)(包含默認(rèn)方法)
          @Override
          void pint02() { //一旦我把print2方法的改為默認(rèn),就報(bào)錯(cuò),而根據(jù)實(shí)現(xiàn)接口的子類方法訪問權(quán)限必須 >= 接口抽象方法的訪問權(quán)限,
                          //那就證明接口的抽象方法的訪問權(quán)限默認(rèn)是public 
          }
      
          @Override
          public void absMethod1() {
      
          }
      
          @Override
          public void absMethod2() {
      
          }
      }
      
      //抽象類
      abstract class absClass implements interfaceDemo{
          //不報(bào)錯(cuò),說明抽象類可以不用實(shí)現(xiàn)接口的抽象方法
      }
      
      //測試類
      public class Interface02 {
          public static void main(String[] args) {
              //接口里的靜態(tài)方法直接用接口名調(diào)用,跟類的靜態(tài)方法調(diào)用一樣
              interfaceDemo.print01();
              //默認(rèn)方法接口自己無法使用接口名調(diào)用,只能給實(shí)現(xiàn)了接口的子類調(diào)用
              //interfaceDemo.print02();
      
          }
      }
      
      小細(xì)節(jié):
      1、在jdk1.8后,接口里可以有 靜態(tài)方法 和 默認(rèn)方法的實(shí)現(xiàn) 及定義接口自己屬性
      2、接口里的屬性必須定義時(shí)給定初始值,等同于常量屬性
      3、接口里的靜態(tài)方法直接用接口名調(diào)用,跟類的靜態(tài)方法調(diào)用一樣
      4、默認(rèn)方法接口自己無法使用接口名調(diào)用,只能給實(shí)現(xiàn)了接口的子類調(diào)用
      5、實(shí)現(xiàn)接口的子類方法權(quán)限 >= 接口的抽象方法訪問權(quán)限
      6、抽象類可以實(shí)現(xiàn)接口,但可以實(shí)現(xiàn)接口的抽象方法
      7、接口可以繼承別的接口,但是不能繼承普通類,當(dāng)然也包含抽象類
      
      //注意:
      1、當(dāng)多個(gè)接口里如果有重名的抽象方法,不會(huì)影響使用,如果是重名的常量屬性時(shí),調(diào)用時(shí)使用接口名.屬性名區(qū)分
      
      
      7.2、繼承與接口在應(yīng)用上有什么區(qū)別?
      1、接口其實(shí)是對(duì)java單繼承缺點(diǎn)的一種彌補(bǔ)和擴(kuò)展,讓子類有更豐富的方法和屬性,而這些屬性來源于子類實(shí)現(xiàn)接口里的抽象方法!
      
      #栗子
      
      package P3;
      
      //猴子父類
      class Monkey{
          private String name;
      
          public Monkey(String name){
              this.name = name;
          }
          public String getName(){
              return name;
          }
          //爬樹
          public void climbTree(){
              System.out.println(getName()+"會(huì)爬樹");
          }
      }
      //想要給悟空加技能,會(huì)上天飛,會(huì)下海潛,使用實(shí)現(xiàn)接口的抽象方法
      interface FlightClass{
          public void flight();//會(huì)飛行
      }
      interface DivingClass{
          public void diving();//會(huì)潛水
      }
      
      //孫悟空類
      class sunMonkey extends Monkey implements DivingClass,FlightClass{
      
          public sunMonkey(String name) {
              super(name);
          }
      
          @Override
          public void climbTree() {
              super.climbTree();
          }
      
          //實(shí)現(xiàn)飛行和潛水方法
          @Override
          public void diving(){
              System.out.println(getName()+"會(huì)潛水");
          }
          @Override
          public void flight(){
              System.out.println(getName()+"會(huì)飛行");
          }
      }
      
      //測試類
      public class Relation {
          public static void main(String[] args) {
              new sunMonkey("孫悟空").diving();
              new sunMonkey("孫悟空").flight();
              new sunMonkey("孫悟空").climbTree();
      
              //接口多態(tài),跟普通類多態(tài)一樣具有多態(tài)參數(shù)和多態(tài)數(shù)組特性
              test1(new sunMonkey("孫大圣"));
              test2(new sunMonkey("孫大圣"));
              test3(new sunMonkey("孫大圣"));
          }
      
      //在別的類的方法中去接收父類對(duì)象和實(shí)現(xiàn)接口方法的對(duì)象,這就是多態(tài)
          public static void test1(Monkey monkey){
              monkey.climbTree();
          }
          public static void test2(DivingClass divingClass){
              divingClass.diving();
          }
          public static void test3(FlightClass flightClass){
              flightClass.flight();
          }
      }
      
      輸出:
      孫悟空會(huì)潛水
      孫悟空會(huì)飛行
      孫悟空會(huì)爬樹
      孫大圣會(huì)爬樹
      孫大圣會(huì)潛水
      孫大圣會(huì)飛行
      
      
      7.3、接口的多態(tài)性
      # 接口的多態(tài)跟類的多態(tài)差不多,也有多態(tài)參數(shù)和多態(tài)數(shù)組的特性
      
      1、多態(tài)參數(shù) 與 多態(tài)數(shù)組
      代碼舉栗:
      
      package P3;
      
      import org.omg.CORBA.PUBLIC_MEMBER;
      
      //游戲接口
      interface IGame{
          public void loading();
          public void start();
          public void end();
      }
      
      //游戲類
      class Game{
          private String gameName;
      
          public Game(){};
          public Game(String gameName){ this.gameName = gameName;}
      
          public String getGameName(){ return gameName;}
      
          //游戲運(yùn)行
          public void runGame(IGame iGame){
              //這里使用接口引用去接收實(shí)現(xiàn)該接口的類的對(duì)象,體現(xiàn)了接口的多態(tài)參數(shù)
              iGame.loading();
              iGame.start();
              iGame.end();
          }
      }
      
      //LOL
      class LOL extends Game implements IGame {
      
          public LOL(){}
      
          public LOL(String gameName){ super(gameName);}
      
          @Override
          public void loading() {
              System.out.println(getGameName()+"正在加載....");
          }
      
          @Override
          public void start() {
              System.out.println(getGameName()+"加載完成,可以開始游戲啦....");
          }
      
          @Override
          public void end() {
              System.out.println(getGameName()+"正在關(guān)閉游戲....");
          }
      
          //獨(dú)特方法
          public void lolObject(){
              System.out.println(getGameName()+"是5v5推塔游戲");
          }
      }
      
      //CF
      class CF extends Game implements IGame{
      
          public CF(){}
      
          public CF(String gameName) {
              super(gameName);
          }
      
          @Override
          public void loading() {
              System.out.println(getGameName()+"正在加載....");
          }
      
          @Override
          public void start() {
              System.out.println(getGameName()+"加載完成,可以開始游戲啦....");
          }
      
          @Override
          public void end() {
              System.out.println(getGameName()+"正在關(guān)閉游戲....");
          }
      
          //獨(dú)特方法
          public void cfObject(){
              System.out.println(getGameName()+"是多人槍戰(zhàn)游戲");
          }
      }
      
      //測試類
      public class Relation {
          public static void main(String[] args) {
              //接口多態(tài)參數(shù)的體現(xiàn)
              Game game = new Game("LOL");
              game.runGame(new LOL("LOL"));
              game.runGame(new CF("CF"));
              System.out.println("----------------------");
      
              //接口多態(tài)數(shù)組的體現(xiàn)
              IGame[] iGames = new IGame[]{new LOL("英雄聯(lián)盟"),new CF("穿越火線")};
              for (IGame i: iGames) {
                  if (i instanceof LOL){
                      //如果想調(diào)用子類對(duì)象的獨(dú)特方法,可以使用instanceof進(jìn)行對(duì)象類型判斷,
                      ((LOL) i).lolObject();
                  }else { ((CF)i).cfObject();}
              }
          }
      }
      
      輸出:
      LOL正在加載....
      LOL加載完成,可以開始游戲啦....
      LOL正在關(guān)閉游戲....
      CF正在加載....
      CF加載完成,可以開始游戲啦....
      CF正在關(guān)閉游戲....
      ----------------------
      英雄聯(lián)盟是5v5推塔游戲
      穿越火線是多人槍戰(zhàn)游戲
      
      
      
      
      2、接口存在多態(tài)傳遞特性
      
      代碼舉栗:
      
      package p4;
      
      import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
      
      //測試類
      public class Interface{
          public static void main(String[] args) {
              Son son = new Son();
              //這是實(shí)現(xiàn)了子接口Ison的子類Son對(duì)象
      
              ISon iSon = son;
              //這里可以把son對(duì)象賦值給子接口ISon的引用,說明子接口引用是可以指向并接收Son類對(duì)象的
      
              IFather iFather = son;
              //這里可以把son對(duì)象賦值給父接口IFather的引用,說明父接口引用是可以指向并接收Son類對(duì)象的
      
              Father father = son;
              //這里可以把son對(duì)象賦值給父類Father的引用,說明父類引用是可以指向并接收Son類對(duì)象的
          }
      }
      
      //父接口
      interface IFather{
          public void father();
      }
      
      //子接口
      interface ISon extends IFather{
          public void son();
      }
      
      //父類
      class Father {
          public void print(){
              System.out.println("這是父類的print()方法");
          }
      }
      //子類
      class Son extends Father implements ISon{
          @Override
          public void son(){
              System.out.println("這是子接口的son()方法");
          }
      
          @Override
          public void father(){
              System.out.println("這是父接口的father()方法");
          }
      }
      
      
      小結(jié):
      1、當(dāng)一個(gè)接口B繼承接口A,而子類b繼承父類a,而b實(shí)現(xiàn)接口B方法時(shí),b類對(duì)象可以傳遞給接口B的所有父接口的接口引用,這就是接口的多層傳遞
      
      
      
      3、多態(tài)參數(shù)與多態(tài)數(shù)組在使用上的區(qū)別?
      
      1、多態(tài)數(shù)組在程序運(yùn)行時(shí),所有繼承的子類對(duì)象或?qū)崿F(xiàn)接口抽象方法的類對(duì)象,可以以數(shù)組的方式同時(shí)傳遞多個(gè)對(duì)象給父類引用
      
      2、而參數(shù)多態(tài)只能同時(shí)傳遞一種類對(duì)象
      
      3、所以當(dāng)需要使用多個(gè)不同類對(duì)象時(shí),使用多態(tài)數(shù)組;反之,使用多態(tài)參數(shù)就可以了
      
      
      
      
      4、小練習(xí)
      //課后小練習(xí):以下程序輸出什么?如有錯(cuò)誤,請(qǐng)修改
      interface A{ int a = 0;}
      
      class B{ int a = 1;}
      
      class C extends B implements A{
          public void method1(){
              System.out.println(a); 
              
          }
      
          public static void main(String[] args) {
              new C().method1();
          }
      }
      
      解:
      錯(cuò)誤:調(diào)用a會(huì)有歧義。如果想調(diào)用接口的a,使用接口名A.a ; 如果想用B類的a,使用super.a
      
      
      8、內(nèi)部類
      8.1 、內(nèi)部類介紹
      1、內(nèi)部類介紹:
      #一個(gè)類中有嵌入一個(gè)完整的類結(jié)構(gòu),這個(gè)嵌套的類稱為內(nèi)部類
      
      內(nèi)部類特點(diǎn):
      1、內(nèi)部類可以直接訪問外層類的私有屬性
      2、內(nèi)部類的作用域在它的外部類中
      3、本質(zhì)上其實(shí)也是外部類的一個(gè)成員,其他都一樣
      
      內(nèi)部類定義格式:
      
      class Outer{ //外部類
      
      class Inner{//內(nèi)部類
      
      public void Method1(){
      class Inner01{} //方法里的內(nèi)部類
      }
      }
      } 
      
      調(diào)用內(nèi)部類格式:
      new 外部類().new 內(nèi)部類().內(nèi)部類方法名或?qū)傩?
      代碼舉栗:
      //外部類
      class A{
          private int a = 1;
          private void A(){
              System.out.println("這是外層類的A方法");
          }
      
          //內(nèi)部類
          class Inner{
              public void print(){
                  System.out.println(a);
              }
          }
      
      
          public static void main(String[] args) {
              new A().new Inner().print();
          }
      }
      輸出:
          1
          
          
          
      2、內(nèi)部類的分類:
      
      *在外部類的方法中
      1、局部內(nèi)部類(有類名)
      2、匿名內(nèi)部類(沒有類名,這是重點(diǎn),常用)
      
      *類似外部類的成員類
      1、成員內(nèi)部類(沒用static修飾)
      2、靜態(tài)內(nèi)部類(用static修飾)
      
      
      8.2、局部內(nèi)部類
      1、局部內(nèi)部類的介紹:
      
      訪問權(quán)限: 可以訪問外部類所有成員和自己的成員
      
      位置: 定義在外部類的方法或代碼塊中
      
      修飾符: 只能使用final常量修飾符,因?yàn)樗淖饔糜騼H限于局部方法中,局部變量不能用修飾符,但final可以
      
      作用域: 僅在外部類的方法或代碼塊中
      
      
      
      #使用局部內(nèi)部類舉栗:
      
      //外部類
      class A{
          private int a = 1;
      
          public void f1(){
              
              //外部類訪問局部內(nèi)部類
          };
      
          //外部類
          class C1{ public void m1(){}};
      
          private void print(){
              class LocalInnerClass{
                  public void LocalInnerMethod(){
                      System.out.println("這是局部內(nèi)部類的方法");
      
                      //局部內(nèi)部類-->訪問-->外部類成員-->直接訪問
                      f1();
                      System.out.println(a);
                  }
              }
              //如果想在外部類調(diào)用局部內(nèi)部類里的方法,這里得先這樣
              new LocalInnerClass().LocalInnerMethod();
          }
          public static void main(String[] args) {
              new A().print();
          }
      }
      
      
      8.3、匿名內(nèi)部類
      1、匿名內(nèi)部類的介紹
      
      
      方式一(使用接口名new)、
      
      //接口
      interface Interface1{
          public void print();
      }
      
      
      class Anonymous {
          
          public void Method() {
              /*這是匿名內(nèi)部類方式一、
              * 解讀:
              *1、編譯類型是接口Interface1,
              *2、運(yùn)行類型是:
              * new Interface1() {
                  @Override
                  public void print() {
                      System.out.println("這是匿名內(nèi)部類");
                  }
              };
              * 3、匿名內(nèi)部類是一個(gè)對(duì)象,也相當(dāng)于實(shí)現(xiàn)接口Interface1的無名子類
              * */
              Interface1 i = new Interface1() {
                  @Override
                  public void print() {
                      System.out.println("這是匿名內(nèi)部類");
                  }
              };
              i.print();
          }
          
          //測試
          public static void main(String[] args) {
              new Anonymous().Method();
          }
      }
      
      
      
      方式二(使用類名new)、
      
      package p4;
      
      //接口
      interface Interface1{
          public void print();
      }
      
      
      class  FatherClass{
          public void test(){}
      }
      
      
      class Anonymous {
      
          public void Method() {
              /*這是匿名內(nèi)部類方式一、
              * 解讀:
              *1、可以理解為:相當(dāng)于接口Interface1的子類的實(shí)例對(duì)象
              *2、編譯類型是接口Interface1,
              *3、運(yùn)行類型是: class p4.Anonymous$1 表示Anonymous編號(hào)為1的內(nèi)部類
              Interface1() {
                  @Override
                  public void print() {
                      System.out.println("這是匿名內(nèi)部類");
                  }
              };
              * 3、匿名內(nèi)部類是一個(gè)對(duì)象,也相當(dāng)于實(shí)現(xiàn)接口Interface1的無名子類
              * */
              Interface1 i = new Interface1() {
                  @Override
                  public void print() {
                      System.out.println("這是匿名內(nèi)部類方式一");
                  }
              }; //4、匿名內(nèi)部類尾部記得加;
              i.print();
              System.out.println(i.getClass());
          }
      
          public void Method1(){
              /*匿名內(nèi)部類方式二
              * 1、可以理解為:相當(dāng)于類FatherClass的子類的實(shí)例對(duì)象
              * 2、編譯類型是FatherClass類
              * 3、運(yùn)行類型是: class p4.Anonymous$2 表示Anonymous編號(hào)為2的內(nèi)部類
              FatherClass() {
                  @Override
                  public void test() {
                      System.out.println("這是匿名內(nèi)部類方式二");
                  }
              };
              * */
              FatherClass father = new FatherClass() {
                  @Override
                  public void test() {
                      System.out.println("這是匿名內(nèi)部類方式二");
                  }
              };father.test();
              System.out.println(father.getClass());
          }
      
          //測試
          public static void main(String[] args) {
              new Anonymous().Method();//匿名內(nèi)部類方式一
              new Anonymous().Method1();//匿名內(nèi)部類方式二
          }
      }
      
      輸出:
      這是匿名內(nèi)部類方式一
      class p4.Anonymous$1
      這是匿名內(nèi)部類方式二
      class p4.Anonymous$2
      
      
      
      2、匿名內(nèi)部類的調(diào)用特點(diǎn):
      1、通過對(duì)象本身調(diào)用內(nèi)部類的方法
       new FatherClass() {
                  @Override
                  public void test() {
                      System.out.println("這是匿名內(nèi)部類方式二");
                  }
              }.test();
              
              
      2、通過對(duì)象引用調(diào)用本身內(nèi)部的方法
       FatherClass father = new FatherClass() {
                  @Override
                  public void test() {
                      System.out.println("這是匿名內(nèi)部類方式二");
                  }
              };father.test();
      
      
      
      3、匿名內(nèi)部類的應(yīng)用場景
      1、當(dāng)作實(shí)參直接傳遞
      
      代碼舉栗:
      
      public class Anonymous01 {
          public static void main(String[] args) {
              Kitchen kitchen = new Kitchen();
              /**
               * 1、匿名內(nèi)部類只執(zhí)行一次,適合作參數(shù)進(jìn)行傳遞
               * */
              kitchen.rinseFood(new Soup(){
                  public void cooking(){
                      System.out.println("午餐吃陽澄湖大閘蟹");
                  }
                  public void stewSoup(){
                      System.out.println("加三鮮湯");
                  }
              });
      
      
              kitchen.rinseFood(new Soup() {
                  @Override
                  public void cooking() {
                      System.out.println("午餐吃糖醋排骨");
                  }
      
                  @Override
                  public void stewSoup() {
                      System.out.println("加排骨蘿卜湯");
                  }
              });
          }
      }
      
      //烹飪接口
      interface ICook{ void cooking();}
      
      //煮湯接口
      interface Soup extends ICook{ void stewSoup();}
      
      //廚房類
      class Kitchen {
          //洗菜方法
          public void rinseFood(Soup soup){
              soup.cooking();
              soup.stewSoup();
          }
      }
      
      輸出:
      午餐吃陽澄湖大閘蟹
      加三鮮湯
      午餐吃糖醋排骨
      加排骨蘿卜湯
      
      
      
      4、如何使用多態(tài)機(jī)制把局部內(nèi)部類接到外部類使用
      
      ##### 1、使用接口接收
      
      ?```
      package p5;
      
      public class Test {
      
          public static void main(String[] args) {
              /**
               * 1、frock類型class p5.Frock; inner類型是class p5.Frock$1InnerH3
               * 2、frock.h2()返回對(duì)象類型是其實(shí)是實(shí)現(xiàn)接口InnerH3類的對(duì)象類型,
               * 屬于外部類Frock的成員,所以不需要向下轉(zhuǎn)型
               * */
              Frock frock = new Frock();
              Inner inner = frock.h2();
              inner.show();
              System.out.println(frock.getClass());
              System.out.println(inner.getClass());
          }
      }
      
      //1、使用接口把內(nèi)部類InnerH3接出來
      interface Inner{ public void show();}
      
      //使用子類把InnerH3接出來
      
      
      //外部類Frock
      class Frock {
          int a1 = 20;
          //局部內(nèi)部類
          public Inner h2(){
              class InnerH3 implements Inner{
                  int a1 = 10;
                  public void show(){
                      System.out.println("------------------");
                      //內(nèi)部類成員與外部類成員重名時(shí),在內(nèi)部類調(diào)用屬性遵循就近原則
                      System.out.println("局部內(nèi)部類-a1:"+a1);
                      //調(diào)用外部類成員名使用必須 外部類名.this.重名屬性名,this.重名屬性名都不行
                      System.out.println("外部類屬性-a1:"+Frock.this.a1);
                  }
              }
              InnerH3 innerH3 = new InnerH3();
              innerH3.show();
              return innerH3;
          }
      
      }
      
      輸出:
      ------------------
      局部內(nèi)部類-a1:10
      外部類屬性-a1:20
      ------------------
      局部內(nèi)部類-a1:10
      外部類屬性-a1:20
      class p5.Frock
      class p5.Frock$1InnerH3
      ?```
      
      
      
      ##### 2、使用抽象類接收
      
      package p5;
      
      public class Test1 {
          public static void main(String[] args) {
              /**分析:
               * 1、frock1對(duì)象類型是class p5.Frock1,
               * 而inner1類型是 class p5.Frock1$1InnerH3,所以需要向下轉(zhuǎn)型
               * 2、 frock1.h2()返回對(duì)象是抽象類的子類,轉(zhuǎn)成抽象類類型Inner1時(shí),所以需要向下轉(zhuǎn)型
               * */
              Frock1 frock1 = new Frock1();
              Inner1 inner1= (Inner1) frock1.h2();
              inner1.show();
              System.out.println(frock1.getClass());
              System.out.println(inner1.getClass());
          }
      }
      
      //1、使用接口把內(nèi)部類InnerH3接出來
      //interface Inner{ public void show();}
      
      //2、使用抽象類把InnerH3接出來
      abstract class  Inner1{  //
          /**第一步,建一個(gè)抽象類和抽象方法,
           * 給h2()方法提供一個(gè)接受內(nèi)部類對(duì)象
           * */
          public void show(){}
      }
      
      //外部類Frock
      class Frock1 {
          int a1 = 20;
          //局部內(nèi)部類
          public Inner1 h2(){
              /**
               * 第二步,讓內(nèi)部類繼承抽象類,
               * 然后返回內(nèi)部類對(duì)象,讓抽象類接收
               * */
              class InnerH3 extends Inner1{
                  int a1 = 10;
                  public void show(){
                      System.out.println("------------------");
                      //內(nèi)部類成員與外部類成員重名時(shí),在內(nèi)部類調(diào)用屬性遵循就近原則
                      System.out.println("局部內(nèi)部類-a1:"+a1);
                      //調(diào)用外部類成員名使用必須 外部類名.this.重名屬性名,this.重名屬性名都不行
                      System.out.println("外部類屬性-a1:"+Frock1.this.a1);
                  }
              }
              InnerH3 innerH3 = new InnerH3();
              innerH3.show();
              return innerH3;
          }
      }
      
      
      8.4、 成員內(nèi)部類
      1、成員內(nèi)部類介紹:
      1、顧名思義,就是定義在外部類的成員位置(除方法中外),沒有static修飾,可以直接訪問外部類的所有成員,包括私有屬性!
      
      2、它可以使用任何訪問修飾符,因?yàn)樗牡匚粚儆诔蓡T而不是局部
      
      3、如果成員內(nèi)部類的成員與外部類的成員有重名的,那么在內(nèi)部類調(diào)用內(nèi)部類成員,直接調(diào)用;在內(nèi)部類調(diào)用外部類重名成員時(shí),使用 外部類名.this.重名成員名
      
      
      格式長這樣:
      class OtherClass{
      private String str="老黃牛"
      class InnerClass{
      public void show(){
      System.out.println("向"+str+"學(xué)習(xí)")
      }
      }
      }
      
      
      
      代碼舉栗(成員內(nèi)部類):
      
      package p5;
      
      public class Test01 {
          public static void main(String[] args) {
              //調(diào)用成員內(nèi)部類方式一、
              OtherClass otherClass = new OtherClass();
              otherClass.new InnerClass().show();
      
              //方式二、
              otherClass.Method().show();
          }
      }
      class OtherClass{
          private String str="老黃牛";
      
          private void PMethod(){
              System.out.println("我是私有方法");
          }
      
          //成員內(nèi)部類
          class InnerClass{
              public InnerClass show(){
                  //1、成員內(nèi)部類訪問外部類,直接訪問
                  System.out.println("向"+str+"學(xué)習(xí)");
                  PMethod();
                  return null;
              }
          }
      
          public InnerClass Method(){
              //2、外部類訪問成員內(nèi)部類的成員,先創(chuàng)建內(nèi)部類對(duì)象.成員
              return new InnerClass();
          }
      }
      
      
      
      
      2、如果內(nèi)部成員類被私有化了,外部其他類還是想訪問該私有成員類中的方法呢,怎么辦呢?還是用接口接出來
      
      代碼舉栗:
      
      方式一、接口
      
      package p5;
      
      import javax.jws.Oneway;
      
      public class Test01 {
          public static void main(String[] args) {
              //方式一、接口
              OtherClass otherClass = new OtherClass();
              I i = otherClass.PMethod();
              i.show();
          }
      }
      
      //方式一、接口
      interface I{ public void show();}
      
      //方式二、抽象類
      //abstract class ABS{ public void show(){}}
      
      class OtherClass{
          private String str="老黃牛";
      
      
          public InnerClass PMethod(){
              return new InnerClass();
          }
      
          //成員內(nèi)部類
          private class InnerClass implements I{
              public void show(){
                  //1、成員內(nèi)部類訪問外部類,直接訪問
                  System.out.println("向"+str+"學(xué)習(xí)");
                  PMethod();
              }
          }
      }
      輸出:
      向老黃牛學(xué)習(xí)
      
      -------------------------------------------------------------------------------
      
      方式二、抽象類
      
      package p5;
      
      public class Test02 {
          public static void main(String[] args) {
              //方式二、抽象類
              OtherClass01 otherClass01 = new OtherClass01();
              ABS abs = (ABS)otherClass01.PMethod();
              abs.show();
          }
      }
      
      //方式二、抽象類
      abstract class ABS{ public void show(){}}
      
      
      //外部類
      class OtherClass01{
          private String str="老黃牛";
      
          public InnerClass PMethod(){
              return new InnerClass();
          }
      
          //成員內(nèi)部類
          private class InnerClass extends ABS{
              public void show(){
                  //1、成員內(nèi)部類訪問外部類,直接訪問
                  System.out.println("向"+str+"學(xué)習(xí)");
                  PMethod();
              }
          }
      }
      輸出:
      向老黃牛學(xué)習(xí)
      
      
      
      
      3、如果成員內(nèi)部類的成員與外部類的成員有重名的,那么調(diào)用在內(nèi)部類調(diào)用外部類成員,直接調(diào)用; 在外部類調(diào)用內(nèi)部類成員時(shí),使用 外部類名.this.內(nèi)部類成員名
      
      
      8.5、 靜態(tài)內(nèi)部類
      1、靜態(tài)內(nèi)部類的介紹
      
      1、靜態(tài)內(nèi)部類 = 使用static修飾內(nèi)部類
      
      2、跟成員內(nèi)部類其他的相同,唯一區(qū)別就是:靜態(tài)內(nèi)部類只能訪問外部類的靜態(tài)成員
      
      
      
      2、靜態(tài)內(nèi)部類的使用方式:
      
      package p5;
      
      public class Test03 {
          public static void main(String[] args) {
              //方式二、
              new OtherClass02().Method01();
              
              //方式一
              OtherClass02.Method01();
          }
      }
      
      //外部類
      class OtherClass02{
          private static int a1 = 1;
          private int a2 = 2;
          static class InnerClass02{
              public void Method(){
                  System.out.println("外部類屬性a1:"+a1);
              }
          }
          //在外部其他類,使用靜態(tài)內(nèi)部類的Method()方法
          //方式一、使用靜態(tài)方法直接調(diào)用靜態(tài)方法
          public static void Method01(){
              new InnerClass02().Method();
          }
      
          //方式二、使用該方法返回一個(gè)靜態(tài)內(nèi)部類對(duì)象
          public InnerClass02 Method02(){
              return new InnerClass02();
          }
      }
      
      
      
      3、當(dāng)靜態(tài)內(nèi)部類成員與外部類成員出現(xiàn)重名時(shí),在內(nèi)部類調(diào)用內(nèi)部類重名的成員時(shí),直接調(diào)用; 在靜態(tài)內(nèi)部調(diào)用外部類靜態(tài)重名成員,使用外部類名.重名成員名
      
      #這里就不寫代碼舉栗了
      
      
      9、枚舉
      9.1、枚舉的介紹
      1、枚舉的介紹:
      1、枚舉是一種特殊的類,用于表示一組常量,比如性別只有男和女,一天只有24小時(shí)等常識(shí)常量
      
      2、使用關(guān)鍵字euum來定義,常量名使用大寫,各常量之間使用,分割。 如eunum Sex{ MAN,WOWAN; }
      
      
      
      
      
      2、枚舉的實(shí)現(xiàn)方式:
      
      
      1) 方式一、自定義枚舉
      
      public class Custom {
          public static void main(String[] args) {
              //類似調(diào)用靜態(tài)屬性調(diào)用,類名.屬性名
              System.out.println(Season.spring);
              System.out.println(Season.summer);
              System.out.println(Season.autumn);
              System.out.println(Season.winter);
          }
      }
      
      //自定義枚舉: 季節(jié)類
      class Season{
          private String name;
          private String description;
      
          //把構(gòu)造器私有化,不給外部new新的對(duì)象
          private Season(String name, String description) {
              this.name = name;
              this.description = description;
          }
      
          //外部只能讀取不能修改
          public String getName() {
              return name;
          }
          public String getDescription() {
              return description;
          }
      
          //使用static + final是為了優(yōu)化底層(不會(huì)觸發(fā)類加載,但是這里new對(duì)象還是會(huì)類加載)
          public static final Season spring = new Season("春季","溫暖");
          public static final Season summer = new Season("夏季","炎熱");
          public static final Season autumn = new Season("秋季","肅殺");
          public static final Season winter = new Season("冬季","寒冷");
      
          @Override
          public String toString() {
              return "季節(jié):" + name + "  特點(diǎn):"+ description;
          }
      }
      
      
      自定義枚舉注意點(diǎn):
      1、構(gòu)造器私有化
      2、本類內(nèi)部使用 static+final 創(chuàng)建一組對(duì)象,對(duì)外暴露對(duì)象
      3、只提供get方法,不提供set方法
      
      
      
      
      
      2)方式二、使用enum關(guān)鍵字
      
      package p5;
      
      public class Custom {
          public static void main(String[] args) {
              //類似調(diào)用靜態(tài)屬性調(diào)用,類名.屬性名
              System.out.println(Season1.SPRING);
              System.out.println(Season1.SUMMER);
              System.out.println(Season1.AUTUMN);
              System.out.println(Season1.WINTER);
          }
      }
      
      //使用enum關(guān)鍵字實(shí)現(xiàn)枚舉
      enum Season1 {
      //這個(gè)必須寫到這個(gè)enum類的首行
      //使用enum關(guān)鍵字,默認(rèn)會(huì)讓Season1繼承Enumeration這個(gè)類
      
          SPRING("春季", "溫暖"),
          SUMMER("夏季", "炎熱"),
          AUTUMN("秋季", "肅殺"),
          WINTER("冬季", "寒冷");
      
          private String name;
          private String description;
      
          private Season1(String name, String description) {
              this.name = name;
              this.description = description;
          }
      
          public String getName() {
              return name;
          }
      
          public String getDescription() {
              return description;
          }
      
          @Override
          public String toString() {
              return "季節(jié):" + name + "  特點(diǎn):"+ description;
          }
      }
      
      
      小結(jié)(用enum關(guān)鍵字實(shí)現(xiàn)枚舉注意細(xì)節(jié))
      1、枚舉常量必須放在枚舉類首行
      2、當(dāng)有多個(gè)枚舉對(duì)象時(shí),使用,隔開,用;結(jié)束
      3、public static final Season1  枚舉對(duì)象 = new Seson1("春天","溫暖"); 等同于 SPRING("春天","溫暖"),
      
      
      
      9.2、枚舉的常用方法
      1、toString: Enum類已重寫過,返回的是當(dāng)前對(duì)象名(大寫),子類可重寫該方法,用于返回自定義的對(duì)象屬性信息
      2、name: 返回當(dāng)前對(duì)象名(常量名),子欸不能重寫 
      3、ordinal: 返回當(dāng)前對(duì)象的位置編號(hào),默認(rèn)從0開始
      4、values: 返回當(dāng)前枚舉類的所有常量
      5、valueOf; 將字符串轉(zhuǎn)成枚舉對(duì)象,要求字符串必須為已存在的常量名,否則報(bào)異常
      6、compareTo: 比較兩個(gè)枚舉常量的位置編號(hào),
      
      
      
      代碼舉栗:
      
      package p5;
      
      import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
      
      public class Custom {
          public static void main(String[] args) {
              Season1 autumn = Season1.AUTUMN;
              System.out.println(autumn);//這里已重寫過
              System.out.println(autumn.name());//返回大寫的autumn對(duì)象名:AUTUMN
              System.out.println(autumn.ordinal());//返回該對(duì)象的編號(hào)(理解下標(biāo)也行),用于
              System.out.println(Season1.values());//返回該枚舉中所有對(duì)象,是一個(gè)數(shù)組類型,可迭代
              Season1[] season1s = (Season1.values());
              for (Season1 s:season1s){
                  System.out.println(s);
              }
              System.out.println(Season1.valueOf("SPRING"));//判斷該枚舉中是否有SPRING對(duì)象,有返回該對(duì)象信息,沒有報(bào)異常
          }
      }
      
      //使用enum關(guān)鍵字實(shí)現(xiàn)枚舉
      enum Season1 {
          //這個(gè)必須寫到這個(gè)enum類的首行
          //使用enum關(guān)鍵字,默認(rèn)會(huì)讓Season1繼承Enumeration這個(gè)類
          SPRING("春季", "溫暖"),
          SUMMER("夏季", "炎熱"),
          AUTUMN("秋季", "肅殺"),
          WINTER("冬季", "寒冷");
      
          private String name;
          private String description;
      
          private Season1(String name, String description) {
              this.name = name;
              this.description = description;
          }
      
          public String getName() {
              return name;
          }
      
          public String getDescription() {
              return description;
          }
      
          @Override
          public String toString() {
              return "季節(jié):" + name + "  特點(diǎn):"+ description;
          }
      }
      
      輸出:
      季節(jié):秋季  特點(diǎn):肅殺
      AUTUMN
      2
      [Lp5.Season1;@14ae5a5
      季節(jié):春季  特點(diǎn):溫暖
      季節(jié):夏季  特點(diǎn):炎熱
      季節(jié):秋季  特點(diǎn):肅殺
      季節(jié):冬季  特點(diǎn):寒冷
      季節(jié):春季  特點(diǎn):溫暖
      
      
      10、注解
      1、注解的介紹:
      
      1、注解也稱為元數(shù)據(jù),用于修飾解釋包、類、方法、屬性、構(gòu)造器、局部變量等信息
      
      2、和注釋一相似之處在于它不影響代碼邏輯,不同之處注解可以被編譯貨或運(yùn)行,相當(dāng)于嵌入代碼中的補(bǔ)充信息
      3、使用注解主要是為了標(biāo)記過時(shí)功能、忽略警告信息等
      
      
      10.1、Override

      1、用于限定某個(gè)方法,常用于重寫父類方法,該注解只能用于方法中

      10.2、Deprecated

      1、用于表示某個(gè)程序中的類、方法已過時(shí)

      10.3、supresswarning

      1、用于屏蔽編譯器的警告信息

      11、包裝類與基本數(shù)據(jù)類型
      11.1、包裝類的介紹
      1、在java中,有常見的8種基本數(shù)據(jù)類型,分別為byte、boolean、char、short、int、long、float、double,在工作中需要頻繁使用它們進(jìn)行各種操作。java設(shè)計(jì)者就為每個(gè)基本類型封裝了一個(gè)類并提供常見的方法,大大提高了工作效率,而這些類就是包裝類
      
      2、基本類型 ---> 包裝類
      
      
      基本數(shù)據(jù)類型 包裝類
      boolean Boolean
      char Character
      byte Byte
      short Short
      int Integer
      long Long
      float Float
      double Double
      2、裝箱與拆箱
      裝箱: 基本類型  ————> 包裝類型
      拆箱:包裝類型  ————> 基本類型
      
      
      
      
      3、裝箱拆箱舉栗:
      
      package p5;
      
      public class Packaging {
          public static void main(String[] args) {
              int i = 10;
              //手動(dòng)裝箱(jdk1.5前)
              Integer integer = new Integer(i);
              Integer integer1 = Integer.valueOf(i);//手動(dòng)裝箱調(diào)用的其實(shí)是valueOf()方法
              System.out.println(integer1.getClass());
              System.out.println(integer.getClass()==integer1.getClass());
      
              //手動(dòng)拆箱
              int i1 = integer.intValue();//拆箱調(diào)用的是intValue()方法
              System.out.println(i1);
      
              //自動(dòng)裝箱
              short s = 10;
              Short s1 = s;//底層調(diào)用的還是Short.ValueOf(s)
              System.out.println(s1.getClass());
      
              //自動(dòng)拆箱
              short s2 = s1; //底層調(diào)用的還是shortValue()進(jìn)行拆箱
              System.out.println(s2);
          }
      }
      輸出:
      class java.lang.Integer
      true
      10
      class java.lang.Short
      10
      
      
      11.2、小練習(xí)( 包裝類)
      1、以下輸出結(jié)果是?
      public static void main(String[] args) {
              Integer i = new Integer(1);
              Integer i1 = new Integer(1);
              System.out.println(i==i1);
              //false,new開辟了新的空間,所以不是同一個(gè)對(duì)象,故false
              System.out.println(i.equals(i1));
              //true,底成先判斷兩對(duì)象是否為同一類型對(duì)象,在判斷兩對(duì)象的值是否相等,相等返回true,否則false
      
              Integer m = 1;
              Integer n = 1;
              System.out.println(n==m);
              //true,底層會(huì)先判斷該基本類型的值是否在-128~127之間,是就指向同一對(duì)象,否則new一個(gè)新對(duì)象
      System.out.println(n.equals(m));
      //true,底成先判斷兩對(duì)象是否為同一類型對(duì)象,在判斷兩對(duì)象的值是否相等,相等返回true,否則false
      
              Integer x = 128;
              Integer y = 128;
              System.out.println(x==y);
              //false,超過常量池范圍-128~127之間,new新對(duì)象,不是同一對(duì)象,故false
      System.out.println(x.equals(y));
      //true,底成先判斷兩對(duì)象是否為同一類型對(duì)象,在判斷兩對(duì)象的值是否相等,相等返回true,否則false
         
         }
          
          
          
      2、下面輸出的值是?
      public static void main(String[] args){
      Integer i = 127;
      int i2 = 127;
      System.out.println(i==i2);//true,只要比較時(shí)出現(xiàn)一個(gè)基本數(shù)據(jù)類型,比較的就是值大小
      
      Integer i3 = 128;
      int i4 = 128;
      System.out.println(i3==i4);//true,只要比較時(shí)出現(xiàn)一個(gè)基本數(shù)據(jù)類型,比較的就是值大小
      }
      
      
      小結(jié)(包裝類)
      1、當(dāng)基本數(shù)據(jù)類型與包裝類==比較時(shí),比較的是兩對(duì)象的值
      2、只要是new的對(duì)象,就不可以是同一對(duì)象
      3、當(dāng)兩個(gè)包裝類對(duì)象進(jìn)行==比較時(shí),如果對(duì)象值在-128~127之間,那就指向同一常量池對(duì)象
      
      

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多