前言
最近在學習《java編程思想》 學到了內部類
類不就是class嗎 天天用 還能講出花來了不成...
其實不然,在java中,類的種類和使用方式多種多樣,花樣繁多。其中主要有
普通類
內部類(嵌套類)
匿名類
抽象類
靜態類
密封類
就先講這麼多吧。接下來將從應用場景、定義、實例化、這3個方面入手,瞭解一下關於類的基本常識。
普通類
應用場景
類的由來歸根於物以類聚,人以羣分。將世間萬物相同的特徵和行爲提取(屬性和方法),歸納總結成一個類型。是我們編程世界最常用也是最基礎的單元。
定義
public class cat { public cat(String _color){ this.color=_color; } //屬性 public String color; //方法(行爲) public void run(){ System.out.println(color+"的貓正優雅的向你走來"); } } c.run();
這是最基本的類的使用方式。
內部類
應用場景
內部類也叫嵌套類。
可以細分爲 非靜態內部類、靜態內部類,
它的使用場景較爲廣泛,而且多樣
定義
非靜態內部類
public class InnerClassTest { private String name; public InnerClassTest(String name){ this.name=name; } public class Inner{ public String getName(){ return name; } } public Inner getInnerClass(){ return new Inner(); } }
可以看到我 加粗變色的部分。它定義在一個普通類(外部類)中,它也有自己的屬性和方法,它能訪問到外部類的成員變量,另外爲了方便,一般會在外部中定義一個方法,來對外提供引用,也能夠內部使用
實例化
1 InnerClassTest InnerClassTest=new InnerClassTest("張三"); 2 InnerClassTest.Inner inner=innerClassTest.new Inner(); 3 System.out.println(inner.getName()); 4 InnerClassTest.Inner s= innerClassTest.getInnerClass(); 5 System.out.println(s.getName());
可以看到,如果需要訪問內部類,首先需要有父類的引用。也就是第一行的外部類實例化
第2行和第4行展示了非靜態內部類的2種實例化方式。 一種是.new 內部類 另一種是通過調用外部類中的方法來獲取對象
靜態內部類
應用場景
靜態內部類使用比較少見,參見建造者模式
定義
1 public class InnerClassTest { 2 private static String name; 3 public InnerClassTest(String name){ 4 name=name; 5 } 6 7 public static class Inner{ 8 public static String getName(){ 9 return name; 10 } 11 } 12 public Inner getInnerClass(){ 13 return new inner(); 14 } 15 }
實例化
需要注意的是,內部類如果要將方法設置爲靜態方法,那內部類本身也得是靜態的
String name= InnerClassTest.Inner.getName();
由於是靜態類,所以不需要實例化外部類,直接外部類點出來就行,不過由於外部類name沒有賦值,所以打印出來name是null
匿名類
匿名類被稱爲匿名內部類 ,也是內部類的一致
使用場景
之所以拿出來單獨說,是因爲使用場景極其多。簡化代碼,對於只有一兩個小方法的接口來說,不必創建接口文件,優雅不少 先來舉個栗子
定義
new DataTemplate().exectue(new IDataManager() { @Override public void Process() { System.out.println("執行了接口實現方法"); } });
從變色的部分可以看出,這是個接口,而接口正常情況下是無法new的。在類裏面卻可以隨意使用,只要實現接口的方法即可。
這種使用方式,隨處可見
new TimerTask(){ @Override public void run() { } }
new Runnable(){ @Override public void run() { } };
是不是很熟悉,做異步任務,定時任務常用到。
new Comparator() { @Override public int compare(Object o1, Object o2) { return 0; } @Override public boolean equals(Object obj) { return false; } };
是不是更熟悉了,做排序比較的時候經常用。在java中,匿名類無處不在。
這種簡寫的方式相當於
public class nimingTest implements Comparator { @Override public int compare(Object o1, Object o2) { return 0; } }
抽象類
抽象類顧名思義,將共同特徵抽象出來,提取共同的行爲, 由子類去實現。關鍵字 abstract
在類中加入abstract 它可以沒有抽象方法。相反,一個類中如果有abstract修飾某個方法,它就叫抽象類,而且必須給類加上abstract修飾
使用場景
抽象是軟件工程面向對象中很重要的概念,抽象類和接口很相似,同樣可以由子類重寫實現。不同點在於,接口沒有方法體,而抽象類可以正常擁有屬性和方法體,可以有自己的普通方法。
例如下單綁定卡,卡類就是個抽象類,子類有銀行卡,信用卡,會員卡,積分卡,超市聯名卡 。他們都有共同的屬性,如卡號,類型,擁有共同的支付行爲
常見的有抽象工廠,屬於最常見的設計模式,下單業務邏輯也會有見到抽象的身影。不同類型的訂單執行不同的子類邏輯(如,普通訂單,奪寶,拼團,送禮)
定義
public abstract class nimingTest implements Comparator { @Override public int compare(Object o1, Object o2) { return 0; } }
這個抽象類可以繼承接口,可以不需要抽象方法,不過抽象類無法實例化,因爲不是具象,它需要子類繼承
public class AbstractChildClassTest extends nimingTest { }
實例化
new AbstractChildClassTest().compare(1,2);
此時之類可以訪問父類所有的public方法,如果父類有抽象方法,則子類必須要實現這個方法,除非之類也是一個抽象類。
此時給抽象類加一個抽象方法,讓子類來繼承
public abstract class nimingTest implements Comparator { @Override public int compare(Object o1, Object o2) { return 0; } public abstract String getName(); }
子類
public class AbstractChildClassTest extends nimingTest { @Override public String getName() { return null; } }
使用
new AbstractChildClassTest().compare(1,2); new AbstractChildClassTest().getName();
還可以繞過之類,自己寫匿名類,對付接口的一招也能用於抽象類
new nimingTest() { @Override public String getName() { return ""; } };
可以看到,之前不能new的抽象類,居然能跳過被之類繼承的環境,直接採用匿名的方式實現抽象方法。
使用的時候
String name= new nimingTest() { @Override public String getName() { return "xss"; } }.getName(); System.out.println(name);
靜態類
靜態類屬於比較特殊的存在,因爲在整個內存中只有一份元數據。所以不存在實例化的可能,其實靜態內部類纔算是靜態類。
關鍵字 static
關鍵字無法修飾類(僅限外部類),只能用於成員變量和方法。凡是有方法被static修飾的類,我們叫他靜態類。
靜態變量,靜態塊,靜態方法 靜態內部類
使用場景
一般用於工具類或者類似枚舉的成員變量比較固定的值的地方
定義
如下代碼 展示了 靜態變量,靜態塊,靜態方法,靜態內部類
public class StaticClassTest {
static {
System.out.println("靜態塊做初始化工作");
}
public static int count;
public static int getSum(int a,int b){
return a+b;
}
public static class StaticInnerClass{
public void Register(){
System.out.println("唯一註冊通道");
}
}
}
實例化
靜態相關的 都不需要實例化,內存中僅一份
StaticClassTest.getSum(1,2);
StaticClassTest.count=2;
密封類
密封類也叫最終類。和普通類沒有區別,有屬性有方法。唯一特性:無法被之類繼承
關鍵字:final
使用場景
創造這個類的人員覺得該類以及沒有擴展的必要,也不行任何人擴展它,就會將類 加上final 修飾,使它無法被繼承
定義
public final class InnerTestMain {}
實例化
和正常類一樣new就好啦。密封類在日常使用中見到的極少,使用場景不太廣泛
總結
羅列了一圈下來,才發現,主角是內部類。
算算看,非靜態內部類,匿名內部類,靜態內部類,抽象內部類,抽象靜態內部類。還有lamda表達式,也是用的匿名類。
關於類的知識就講到這裏。