java基礎(13):static、final、匿名對象、內部類、包、修飾符、代碼塊

来源:https://www.cnblogs.com/liuhui0308/archive/2019/10/07/11633060.html
-Advertisement-
Play Games

1. final關鍵字 1.1 final的概念 繼承的出現提高了代碼的復用性,並方便開發。但隨之也有問題,有些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。可是當子類繼承了這些特殊類之後,就可以對其中的方法進行重寫,那怎麼解決呢? 要解決上述的這些問題,需要使用到 ...


1. final關鍵字

1.1 final的概念

繼承的出現提高了代碼的復用性,並方便開發。但隨之也有問題,有些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。可是當子類繼承了這些特殊類之後,就可以對其中的方法進行重寫,那怎麼解決呢?

要解決上述的這些問題,需要使用到一個關鍵字final,final的意思為最終,不可變。final是個修飾符,它可以用來修飾類,類的成員,以及局部變數。

1.2 final的特點

final修飾類不可以被繼承,但是可以繼承其他類。

class Yy {}
final class Fu extends Yy{} //可以繼承Yy類
class Zi extends Fu{} //不能繼承Fu類

final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋後可以加final。

class Fu {
    // final修飾的方法,不可以被覆蓋,但可以繼承使用
    public final void method1(){}
    public void method2(){}
}
class Zi extends Fu {
    //重寫method2方法
    public final void method2(){}
}

final修飾的變數稱為常量,這些變數只能賦值一次。

final int i = 20;
i = 30; //賦值報錯,final修飾的變數只能賦值一次

引用類型的變數值為對象地址值,地址值不能更改,但是地址內的對象屬性值可以修改。

final Person p = new Person();
Person p2 = new Person();
p = p2; //final修飾的變數p,所記錄的地址值不能改變
p.name = "小明";//可以更改p對象中name屬性值

p不能為別的對象,而p對象中的name或age屬性值可更改。

 

修飾成員變數,需要在創建對象前賦值,否則報錯。(當沒有顯式賦值時,多個構造方法的均需要為其賦值。)

class Demo {
    //直接賦值
    final int m = 100;
    
    //final修飾的成員變數,需要在創建對象前賦值,否則報錯。
    final int n; 
    public Demo(){
        //可以在創建對象時所調用的構造方法中,為變數n賦值
        n = 2016;
    }
}

2. static關鍵字

2.1 static概念

當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是通過創建本類對象調用的。當在調用對象的某個方法時,這個方法沒有訪問到對象的特有數據時,方法創建這個對象有些多餘。可是不創建對象,方法又調用不了,這時就會想,那麼我們能不能不創建對象,就可以調用方法呢?

可以的,我們可以通過static關鍵字來實現。static它是靜態修飾符,一般用來修飾類中的成員。

2.2 static特點

被static修飾的成員變數屬於類,不屬於這個類的某個對象。(也就是說,多個對象在訪問或修改static修飾的成員變數時,其中一個對象將static成員變數值進行了修改,其他對象中的static成員變數值跟著改變,即多個對象共用同一個static成員變數)

代碼演示:

class Demo {
    public static int num = 100;
}

class Test {
    public static void main(String[] args) {
        Demo d1 = new Demo();
        Demo d2 = new Demo();
        d1.num = 200;
        System.out.println(d1.num); //結果為200
        System.out.println(d2.num); //結果為200
    }
}

被static修飾的成員可以並且建議通過類名直接訪問。

訪問靜態成員的格式:

類名.靜態成員變數名
類名.靜態成員方法名(參數)
對象名.靜態成員變數名         ------不建議使用該方式,會出現警告
對象名.靜態成員方法名(參數)     ------不建議使用該方式,會出現警告

代碼演示:

class Demo {
    //靜態成員變數
    public static int num = 100;
    //靜態方法
    public static void method(){
        System.out.println("靜態方法");
    }
}
class Test {
    public static void main(String[] args) {
        System.out.println(Demo.num);
        Demo.method();
    }
}

2.3 static註意事項

靜態內容是優先於對象存在,只能訪問靜態,不能使用this/super。靜態修飾的內容存於靜態區。

class Demo {
    //成員變數
    public int num = 100;
    //靜態方法
    public static void method(){
        //this.num; 不能使用this/super。
        System.out.println(this.num);
    }
}

同一個類中,靜態成員只能訪問靜態成員

class Demo {
    //成員變數
    public int num = 100;
    //靜態成員變數
    public static int count = 200;
    //靜態方法
    public static void method(){
        //System.out.println(num); 靜態方法中,只能訪問靜態成員變數或靜態成員方法
        System.out.println(count);
    }
}

main方法為靜態方法僅僅為程式執行入口,它不屬於任何一個對象,可以定義在任意類中。

2.4 定義靜態常量

開發中,我們想在類中定義一個靜態常量,通常使用public static final修飾的變數來完成定義。此時變數名用全部大寫,多個單詞使用下劃線連接。

定義格式:
public static final 數據類型 變數名 = 值;

如下演示:

class Company {
    public static final String COMPANY_NAME = "傳智播客";
    public static void method(){
        System.out.println("一個靜態方法");
    }
}

當我們想使用類的靜態成員時,不需要創建對象,直接使用類名來訪問即可。

System.out.println(Company.COMPANY_NAME); //列印傳智播客
Company.method(); // 調用一個靜態方法

註意:

介面中的每個成員變數都預設使用public static final修飾。

所有介面中的成員變數已是靜態常量,由於介面沒有構造方法,所以必須顯示賦值。可以直接用介面名訪問。

interface Inter {
    public static final int COUNT = 100;
}

訪問介面中的靜態變數

Inter.COUNT

3. 匿名對象

3.1 匿名對象的概念

匿名對象是指創建對象時,只有創建對象的語句,卻沒有把對象地址值賦值給某個變數。

如:已經存在的類:

public class Person{
    public void eat(){
        System.out.println();
    }
}

創建一個普通對象

Person p = new Person();

創建一個匿名對象

new Person();

3.2 匿名對象的特點

創建匿名對象直接使用,沒有變數名。

new Person().eat()  //eat方法被一個沒有名字的Person對象調用了。

匿名對象在沒有指定其引用變數時,只能使用一次。

new Person().eat(); 創建一個匿名對象,調用eat方法
new Person().eat(); 想再次調用eat方法,重新創建了一個匿名對象

匿名對象可以作為方法接收的參數、方法返回值使用

class Demo {
    public static Person getPerson(){
        //普通方式
        //Person p = new Person();    
        //return p;
        
        //匿名對象作為方法返回值
        return new Person(); 
    }
    
    public static void method(Person p){}
}

class Test {
    public static void main(String[] args) {
        //調用getPerson方法,得到一個Person對象
        Person person = Demo.getPerson();
        
        //調用method方法
        Demo.method(person);
        //匿名對象作為方法接收的參數
        Demo.method(new Person());
    }
}

4. 內部類

4.1 內部類概念

什麼是內部類

將類寫在其他類的內部,可以寫在其他類的成員位置和局部位置,這時寫在其他類內部的類就稱為內部類。其他類也稱為外部類。

什麼時候使用內部類

在描述事物時,若一個事物內部還包含其他可能包含的事物,比如在描述汽車時,汽車中還包含這發動機,這時發動機就可以使用內部類來描述。

class 汽車 { //外部類
    class 發動機 { //內部類
  }
}

內部類的分類

內部類分為成員內部類與局部內部類。

我們定義內部類時,就是一個正常定義類的過程,同樣包含各種修飾符、繼承與實現關係等。在內部類中可以直接訪問外部類的所有成員。

4.2 成員內部類

成員內部類,定義在外部類中的成員位置。與類中的成員變數相似,可通過外部類對象進行訪問

定義格式

class 外部類 { 
    修飾符 class 內部類 {
        //其他代碼
    }
}

訪問方式

外部類名.內部類名 變數名 = new 外部類名().new 內部類名();

成員內部類代碼演示

定義類

class Body {//外部類,身體
    private boolean life= true; //生命狀態
     public class Heart { //內部類,心臟
    public void jump() {
         System.out.println("心臟噗通噗通的跳")
            System.out.println("生命狀態" + life); //訪問外部類成員變數
        }
    }
}

訪問內部類

public static void main(String[] args) {
    //創建內部類對象
    Body.Heart bh = new Body().new Heart();
    //調用內部類中的方法
    bh.jump();
}

4.3 局部內部類

局部內部類,定義在外部類方法中的局部位置。與訪問方法中的局部變數相似,可通過調用方法進行訪問

定義格式

class 外部類 { 
    修飾符 返回值類型 方法名(參數) {
    class 內部類 {
      //其他代碼
        }
    }
}

訪問方式

在外部類方法中,創建內部類對象,進行訪問

局部內部類代碼演示

定義類

class Party {//外部類,聚會
    public void puffBall(){// 吹氣球方法
        class Ball {// 內部類,氣球
              public void puff(){
     System.out.println("氣球膨脹了");
        }
    }
//創建內部類對象,調用puff方法
new Ball().puff();
    }
}

訪問內部類

public static void main(String[] args) {
    //創建外部類對象
    Party p = new Party();
    //調用外部類中的puffBall方法
    p.puffBall();
}

4.4 內部類的實際使用——匿名內部類

4.4.1 匿名內部類概念

內部類是為了應對更為複雜的類間關係。查看源代碼中會涉及到,而在日常業務中很難遇到,這裡不做贅述。

最常用到的內部類就是匿名內部類,它是局部內部類的一種。

定義的匿名內部類有兩個含義:

  臨時定義某一指定類型的子類

  定義後即刻創建剛剛定義的這個子類的對象

4.4.2 定義匿名內部類的作用與格式

作用:匿名內部類是創建某個類型子類對象的快捷方式。

格式:

new 父類或介面(){
    //進行方法重寫
};

代碼演示

//已經存在的父類:
public abstract class Person{
    public abstract void eat();
    }
//定義並創建該父類的子類對象,並用多態的方式賦值給父類引用變數
Person  p = new Person(){
    public void eat() {
        System.out.println(“我吃了”);
    }
};
//調用eat方法
p.eat();

使用匿名對象的方式,將定義子類與創建子類對象兩個步驟由一個格式一次完成,。雖然是兩個步驟,但是兩個步驟是連在一起完成的。

匿名內部類如果不定義變數引用,則也是匿名對象。代碼如下:

new Person(){
    public void eat() {
        System.out.println(“我吃了”);
    }
}.eat();

5. 包的聲明與訪問

5.1 包的概念

java的包,其實就是我們電腦系統中的文件夾,包里存放的是類文件。

當類文件很多的時候,通常我們會採用多個包進行存放管理他們,這種方式稱為分包管理。

在項目中,我們將相同功能的類放到一個包中,方便管理。並且日常項目的分工也是以包作為邊界。

類中聲明的包必須與實際class文件所在的文件夾情況相一致,即類聲明在a包下,則生成的.class文件必須在a文件夾下,否則,程式運行時會找不到類。

5.2 包的聲明格式

通常使用公司網址反寫,可以有多層包,包名採用全部小寫字母,多層包之間用”.”連接

類中包的聲明格式:

package 包名.包名.包名…;

如:黑馬程式員網址itheima.com那麼網址反寫就為com.itheima

        傳智播客 itcast.cn  那麼網址反寫就為 cn.itcast

註意:聲明包的語句,必須寫在程式有效代碼的第一行(註釋不算)

代碼演示:

package cn.itcast; //包的聲明,必須在有效代碼的第一行

import java.util.Scanner;
import java.util.Random;

public class Demo {}

5.3 包的訪問

在訪問類時,為了能夠找到該類,必須使用含有包名的類全名(包名.類名)。

包名.包名….類名
如: java.util.Scanner
     java.util.Random
    cn.itcast.Demo
帶有包的類,創建對象格式:包名.類名 變數名 = new包名.類名();
     cn.itcast.Demo d = new cn.itcast.Demo();

前提:包的訪問與訪問許可權密切相關,這裡以一般情況來說,即類用public修飾的情況。

類的簡化訪問

當我們要使用一個類時,這個類與當前程式在同一個包中(即同一個文件夾中),或者這個類是java.lang包中的類時通常可以省略掉包名,直接使用該類。

如:cn.itcast包中有兩個類,PersonTest類,與Person類。我們在PersonTest類中,訪問Person類時,由於是同一個包下,訪問時可以省略包名,即直接通過類名訪問 Person。

類名 變數名 = new類名();
Person p = new Person();

當我們要使用的類,與當前程式不在同一個包中(即不同文件夾中),要訪問的類必須用public修飾才可訪問。

package cn.itcst02;
public class Person {}

5.4 import導包

我們每次使用類時,都需要寫很長的包名。很麻煩,我們可以通過import導包的方式來簡化。

可以通過導包的方式使用該類,可以避免使用全類名編寫(即,包類.類名)。

導包的格式:

import 包名.類名;

當程式導入指定的包後,使用類時,就可以簡化了。演示如下

//導入包前的方式
//創建對象
java.util.Random r1 = new java.util.Random();
java.util.Random r2 = new java.util.Random();
java.util.Scanner sc1 = new java.util.Scanner(System.in);
java.util.Scanner sc2 = new java.util.Scanner(System.in);

//導入包後的方式
import java.util.Random;
import java.util.Scanner;
//創建對象
Random r1 = new Random();
Random r2 = new Random();
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);

import導包代碼書寫的位置:在聲明包package後,定義所有類class前,使用導包import 包名.包名.類名;

6. 訪問修飾符

在Java中提供了四種訪問許可權,使用不同的訪問許可權時,被修飾的內容會有不同的訪問許可權,以下表來說明不同許可權的訪問能力:

 

public

protected

default

private

同一類中

同一包中(子類與無關類)

 

不同包的子類

 

 

不同包中的無關類

 

 

 

 

歸納一下:在日常開發過程中,編寫的類、方法、成員變數的訪問

要想僅能在本類中訪問使用private修飾;

要想本包中的類都可以訪問不加修飾符即可;

要想本包中的類與其他包中的子類可以訪問使用protected修飾

要想所有包中的所有類都可以訪問使用public修飾。

註意:如果類用public修飾,則類名必須與文件名相同。一個文件中只能有一個public修飾的類。

7. 代碼塊

7.1 局部代碼塊

局部代碼塊是定義在方法或語句中

特點:

以”{}”劃定的代碼區域,此時只需要關註作用域的不同即可

方法和類都是以代碼塊的方式劃定邊界的

class Demo{
    public static void main(String[] args)    {
        {
                  int x = 1;
                 System.out.println("普通代碼塊" + x);
        }
        int x = 99;
        System.out.println("代碼塊之外" + x);
    }
}

結果:

普通代碼塊1

代碼塊之外99

7.2 構造代碼塊

構造代碼塊是定義在類中成員位置的代碼塊

特點:

優先於構造方法執行,構造代碼塊用於執行所有對象均需要的初始化動作

每創建一個對象均會執行一次構造代碼塊。

public class Person {
    private String name;
    private int age;
    
     //構造代碼塊
    {
        System.out.println("構造代碼塊執行了");
    }
    Person(){
        System.out.println("Person無參數的構造函數執行");
    }
    Person(int age){
        this.age = age;
        System.out.println("Person(age)參數的構造函數執行");
    }
}
class PersonDemo{
    public static void main(String[] args)    {
        Person p = new Person();
        Person p1 = new Person(23);
    }
}

7.3 靜態代碼塊

靜態代碼塊是定義在成員位置,使用static修飾的代碼塊。

特點:

它優先於主方法執行、優先於構造代碼塊執行,當以任意形式第一次使用到該類時執行。

該類不管創建多少對象,靜態代碼塊只執行一次。

可用於給靜態變數賦值,用來給類進行初始化。

public class Person {
    private String name;
    private int age;
     //靜態代碼塊
    static{
        System.out.println("靜態代碼塊執行了");
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.window相關 二.body相關 三.滾動相關 四.位置精確定位 五.坐標軸 六.width/clientWidth/offsetWidth以及height之間區別 ...
  • ## 今日內容 1. JQuery 基礎: 1. 概念 2. 快速入門 3. JQuery對象和JS對象區別與轉換 4. 選擇器 5. DOM操作 6. 案例 # JQuery 基礎: 1. 概念: 一個JavaScript框架。簡化JS開發 * jQuery是一個快速、簡潔的JavaScript框 ...
  • 1、複雜動畫 (1)涉及到的屬性: animation-name:動畫名稱; animation-duration:單次動畫總時長; animation-timing-function:時間函數; animation-delay:播放前延時的時長; animation-iteration-count ...
  • 1. 類型強制轉換 1.1 string強制轉換為數字 可以用 *1來轉化為數字(實際上是調用 .valueOf方法) 然後使用 Number.isNaN來判斷是否為 NaN,或者使用 a!==a 來判斷是否為 NaN,因為 NaN!==NaN 常用:也可以使用 +來轉化字元串為數字 1.2 obj ...
  • 下表列出了用於操作HTML和CSS的所有方法。 ...
  • 0--前言 對於分散式系統環境,主鍵ID的設計很關鍵,什麼自增intID那些是絕對不用的,比較早的時候,大部分系統都用UUID/GUID來作為主鍵,優點是方便又能解決問題,缺點是插入時因為UUID/GUID的不規則導致每插入一條數據就需要重新排列一次,性能低下;也有人提出用UUID/GUID轉lon ...
  • 中介者模式: 1、定義:用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用, 從而使其耦合鬆散,而且可以獨立地改變它們之間的交互 2、模型結構: (1)抽象中介者(Mediator):它是中介者的介面,提供了同事對象註冊與轉發同事對象信息的抽象方法 (2)具體中介者(Concr ...
  • 1.代碼生成器: [正反雙向](單表、主表、明細表、樹形表,快速開發利器)freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本、處理類、service等完整模塊2.多數據源:(支持同時連接無數個資料庫,可以不同的模塊連接不同數的據庫)支持N個數據源3.阿裡資料庫連 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...