細說java中的類

前言

 最近在學習《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表達式,也是用的匿名類。

關於類的知識就講到這裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章