java:從類(class)的角度結構化總結變量,構造器,代碼塊,內部類及方法

前言

java是一門面向對象的語言,而對象是類的一個實例,有行爲和狀態。類是一個模板,它描述一類對象的行爲和狀態。所以本文將從一個類作爲模板的角度,從結構上對類這個抽象概念進行分析描述。

模板圖

說明:圖中標紅的屬於類這個概念,由於匿名內部類,比較特殊(它與局部類很相似,不同的是它沒有類名,如果某個局部類你只需要用一次,就可以採用局部內部類來定義它)所以在模板圖中就不做展示,關於抽象類會在抽象方法中做說明。

1.成員變量

 1.1常量

         常量是指在程序的整個運行過程中值保持不變的量,常量值又稱爲字面常量,它是通過數據直接表示的。常量不同於常量值,它可以在程序中用符號來代替常量值使用,因此在使用前必須先定義。常量與變量類似也需要初始化,即在聲明常量的同時要賦予一個初始值。常量一旦初始化就不可以被修改。

它的聲明格式爲:

final dataType variableName = value;

其中,final 是定義常量的關鍵字,dataType 指明常量的數據類型,variableName 是變量的名稱,value 是初始值.,例如:

final  int i =5;

1.2靜態常量

由final和static共同修飾的爲靜態常量。例如:

  final static int i=6;

靜態常量和常量的區別:

static+final

  • 靜態常量,編譯期常量,編譯時就確定值。
  • 放於方法區中的靜態常量池。
  • 在編譯階段存入調用類的常量池中
  • 如果調用此常量的類不是定義常量的類,那麼不會初始化定義常量的類,因爲在編譯階段通過常量傳播優化,已經將常量存到調用類的常量池中了

final

  • 常量,類加載時確定或者更靠後。
  • 當用final作用於類的成員變量時,成員變量(注意是類的成員變量,局部變量只需要保證在使用之前被初始化賦值即可)必須在定義時或者構造器中進行初始化賦值
  • 對於一個final變量,如果是基本數據類型的變量,則其數值一旦在初始化之後便不能更改;
  • 如果是引用類型的變量,則在對其初始化之後便不能再讓其指向另一個對象。但是它指向的對象的內容是可變的

1.3.普通變量

在Java語言中,所有的變量在使用前必須聲明。聲明變量的基本格式如下:

type identifier [ = value][, identifier [= value] ...] ;

格式說明:type爲Java數據類型。identifier是變量名。可以使用逗號隔開來聲明多個同類型變量。如:

class Demo{
    int = 5;
}

 1.4靜態成員變量

靜態成員變量:也叫類變量,獨立於方法之外的變量,用 static 修飾。

注意:

static修飾的成員變量屬於類,不屬於某個對象。即:多個對象訪問或修改static修飾的成員變量時,其中一個對象將static成員變量進行了修改,其它的對象的static成員變量值跟着改變,即多個對象共享同一個static成員變量。

舉例如下:創建狗類對象時,默認給值 爲1,之後依次被修改。具體代碼及運行結果如下

public class Demo {
    public static void main(String[] args) {
        //創建對象dog1
        Dog dog1 = new Dog();
        //調用test 方法
        dog1.test();
        //直接通過類名調用,並修改
        Dog.age = 2;
        System.out.println("類名調用修改後的age:"+Dog.age);
        //通過對象修改
        int age = dog1.age;
        age = 3;
        System.out.println("對象調用修改後的age:"+age);

    }
}
//創建狗類
class Dog{
   static int age = 1;
   public void test(){
       System.out.println("狗類中的age:"+age);
   }
}

輸出結果爲:

2.代碼塊

2.1靜態代碼塊

static代碼塊指的是static{}包裹的代碼塊,且靜態代碼只執行一次,可以通過Class.forName("classPath")的方式喚醒代碼的static代碼塊,但是也執行一次。

class Demo{
    //屬性
   static int age;
    //靜態代碼塊
    //靜態信息初始化(預先加載資源)
    static {
        age = 1;
        System.out.println("靜態代碼塊");
    }  
    
}

2.2構造代碼塊

使用{}包裹的代碼區域,這裏的代碼區域特指位於class{}下面的而不是存在於其他type method(){}這類函數下面的代碼區域

class Demo{
  
    {
        System.out.println("構造代碼塊");
    }
   
}

3.構造方法

構造方法,是一種特殊的方法。主要用來在創建對象時初始化對象, 即爲對象成員變量賦初始值,總與new運算符一起使用在創建對象的語句中。特別的一個類可以有多個構造函數 ,可根據其參數個數的不同或參數類型的不同來區分它們,即構造函數的重載。

語法規則:

1.方法名必須與類名相同

2.無返回值類型,也不能用void修飾(有任何返回值類型的方法都不是構造方法)

3.可以指定參數,也可以不指定參數;分爲有參構造方法和無參構造方法

構造方法的特點:

1.當沒有指定構造方法時,系統會自動添加無參的構造方法。

2.構造方法可以重載:方法名相同,但參數不同的多個方法,調用時會自動根據不同的參數選擇相應的方法。

3.構造方法是不被繼承的

4.當我們手動的指定了構造方法時,無論是有參的還是無參的,系統都將不會再添加無參的構造方法。

例如,創建一個Person 類,添加age,name 屬性,並添加無參構造及有參構造

class Person{
    //屬性
    int age;
    String name;
    //無參構造
    public Person() {
    }
    //一個參數構造
    public Person(int age) {
        this.age = age;
    }
    //多個參數的構造
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

4.內部類

4.1成員內部類

首先內部類的概念是:在Java中,可以將一個類定義在另一個類裏面或者一個方法裏面,這樣的類稱爲內部類。

成員內部類:在方法外類內定義類。(具體細節及注意事項等在下面代碼中註明

/**
 * 成員內部類
 */
public class InnerDemo2 {

    public static void main(String[] args) {
        /**
         * 方法一
         */
        //創建成員內部類對象
        Outer2.Inner2 inner2 = new Outer2().in;
        //對象調用內部類方法
        inner2.n();
        /**
         * 方法二
         */
        Outer2.Inner2 inner21 = new Outer2().new Inner2();
        //對象調用內部類方法
        inner2.n();
    }
}

//外部類
class Outer2{
    //屬性
    static int i =1;
    //非靜態屬性,可以通過對象調用
    Inner2 in = new Inner2();
    /**
     * 成員內部類:可以當成一個大的屬性
     * 1.可以定義所有的非靜態信息(屬性,方法)及靜態常量
     * 2.可以被4個訪問權限修飾符修飾及final、abstract
     * 3.可以獲取外部類所有信息
     */
    class Inner2{
        int x=2;
        static final int xx =3;
        //報錯 static 不能修飾
        //static int xxx =4;
        public void n(){
            System.out.println(i);
            m();
        }
    }
    //方法
    public void m(){}
}

4.2靜態內部類

靜態內部類:成員內部類加上static(具體細節及注意事項等在下面代碼中註明

/**
 *靜態內部類
 */
public class InnerDemo3 {
    public static void main(String[] args) {
        //創建靜態內部類對象
        Outer3.Inner3 inner3=new Outer3.Inner3();
        inner3.n();
    }
}

//外部類
class Outer3{
    //屬性
    static int i=1;
    //靜態內部類
    //可以定義所有的信息以及靜態常量
    //可以進行繼承和實現
    //可以被訪問權限修飾符以及final/abstract
    //只能獲取外部類的所有靜態信息
    static class Inner3 extends Object implements Cloneable{
        static final int x=2;
        public void n(){
            System.out.println(i);
        }
    }
    //方法
    public void m(){}
}

5.成員方法

方法的定義:

  • 方法是類或對象的行爲特徵的抽象。
  • Java中的方法不能獨立存在,所有的方法必須定義在類中。
  • 使用 “類名.方法” 或 “對象.方法” 的形式調用。
  • 語法格式:

    權限修飾符 返回值類型 方法名(參數類型 參數名) {

      // 方法體

      // 返回值

    }

5.1靜態方法

靜態方法:static修飾的方法,從屬於類。最常見的main()方法就是一個靜態方法

public class Demo {
    public static void main(String[] args) {
    
    }
}

靜態方法隨着類的加載而加載到方法區的靜態方法區裏,與類同級也叫類方法,通過類名.形式來調用。靜態方法存放在靜態區裏不會被賦予系統默認初始值,當靜態方法被調用時會加載到棧中進行執行(類名.形式--參考如下代碼)。

public class Demo {
    public static void main(String[] args) {
        //直接通過類名.形式來調用
       Dog.eat();
    }
}
//創建狗類
class Dog{
    static void eat(){
        System.out.println("狗吃東西");
    }
}

注意事項:

  • 靜態方法可以重載
  • 靜態方法不能重寫
  • 靜態信息(變量、方法。。)可以使用靜態信息,但是不能直接使用非靜態信息
  • 非靜態信息可以直接使用靜態信息以及非靜態信息
  • this 是非靜態的,靜態方法裏面不能直接使用

5.2普通方法

普通方法:沒有static,final 等關鍵字修飾的方法

  • 可以進行方法的重載
  • 可以進行方法的重寫
//創建狗類
class Dog{
   public void sleep(){
        System.out.println("狗在睡覺");
    }
}

5.3最終方法

最終方法:被 final 修飾的方法

注意事項:

  • 最終方法不能被重寫
  • 最終方法可以重載
  • 最終類和非最終類都可以包含最終方法
public class demo {
    //編寫最終方法add
  public final static int add(int a,int b) {
    return a+b;
  }
}

//此時會報錯“cannot override the final method from demo”
//不能重寫來自demo的最終方法
public class mydemo extends demo{
  public static int add(int a,int b) {
      return a+b;
    }
  public static void main(String[] args)
{
      int x=10;
      int y=2;
      System.out.println(add(x,y));
    }
}
//非最終類包含最終方法
class demo {
    public final static int add(int a,int b) {
        return a+b;
    }
    public static void main(String[] args)
    {
        int x=20;
        int y=5;
        System.out.println(x/y);
        System.out.println(add(x,y));
    }
}
//運行結果:
//4
//25

5.4抽象方法

抽象方法:被關鍵字abstract 修飾的方法

當父類中的某個方法被所有子類進行不同程度的重寫,那麼父類裏的這個方法就沒有實際意義,則捨棄掉方法體,加上 abstract 變成抽象方法(沒有方法體---一定要重寫)。

抽象類

抽象方法所在的類就是抽象類。如果普通類繼承抽象類,那麼需要重寫所有的抽象方法,如果不想重寫,則類需要修改爲抽象類。

注意:

  • 抽象類裏不一定含有抽象方法
  • 抽象類不能創建對象,否則能調用到抽象方法,就會出現問題(可以定義構造方法,但是不能創建對象)
  • 抽象類可以做屬性初始化
  • 抽象方法支持重載(重載只和方法名和參數列表有關)
  • 抽象方法不可以被private/final/static,抽象方法一定需要重寫
  • 抽象類不能被final 修飾,因爲抽象方法一定需要重寫,重寫前提是繼承,最終類沒有子類就不行
  • 抽象類的目的主要是爲了延展類繼承結構
/**
 * 抽象類:Employee
 */
abstract class Employee
{
    //屬性
    private String name;
    private String address;
    private int number;
    //抽象方法
    public abstract double computePay();

}

5.5方法內部類

方法內部類:方法內定義的類。

注意:

  • 方法內部類中可以定義所有的非靜態信息以及靜態常量
  • 方法內部類中可以進行正常的繼承和實現
  • 方法內部類不能被訪問權限修飾符來修飾,但是可以被final、abstrat 修飾
  • 方法內部類可以獲取外部類所有的信息
  • 方法內部類只能獲取本方法中的常量
  • 方法內部類創建對象需要在本方法中
package com.tedu.inner;

/**
 * 方法內部類
 */
public class InnerDemo1 {
    public static void main(String[] args) {
        //外部類對象調用m()方法,執行創建內部類對象的代碼
        new Outer1().m();
    }
}
//外部類

/**
 * 類只能被public default 修飾
 */
 class Outer1{
    //屬性
    int x = 1;
    //方法
    public void m(){
        /**
         * 1.jdk 1.8 開始默認底層加上final
         * 2.jdk1.7 及其以前需要強制加上final
         */
        int k = 10;
        //此處修改k=8 內部類System.out.println(k); 就會報錯
        //k=8;
        //方法內部類
        /**
         * 1.可以定義所以非靜態屬性和方法以及[靜態常量]
         * 2.可以進行正常的繼承和實現
         * 3.不能被訪問權限修飾符修飾,但是可以被final,abstract 修飾
         * 4.方法內部類,可以獲取外部類所有的信息
         * 5.只能獲取本方法中的常量信息
         */
        class Inner1 extends Object implements Cloneable{
            int y = 2;
            //靜態屬性和方法不行
            //靜態區沒有存儲所以
            static final int yy=2;
            public void mn(){
                System.out.println(x);
                n();
                //只有拿本方法中的變量纔會默認加上final,否則不加,比如上面執行k=8時,就
                //不會添加final
                System.out.println(k);
                //報錯,k 默認是常量不能被改變
                //System.out.println(k=1);
            }

        }
        //在本方法中創建內部類實例
        Inner1 inner1 = new Inner1();
        inner1.mn();
    }
    public void n(){}
}

 

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