Java基礎學習筆記十 Java基礎語法之final、static、匿名對象、內部類

final關鍵字

繼承的出現提升了代碼的複用性,並方便開發。但隨之也有問題,有些類在描述完以後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。但是當子類繼承了這些特殊類以後,就能夠對其中的方法進行重寫,那怎麼解決呢?要解決上述的這些問題,須要使用到一個關鍵字final,final的意思爲最終,不可變。final是個修飾符,它能夠用來修飾類,類的成員,以及局部變量。java

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;
    }
}
複製代碼

static關鍵字

當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是經過建立本類對象調用的。當在調用對象的某個方法時,這個方法沒有訪問到對象的特有數據時,方法建立這個對象有些多餘。但是不建立對象,方法又調用不了,這時就會想,那麼咱們能不能不建立對象,就能夠調用方法呢?能夠的,咱們能夠經過static關鍵字來實現。static它是靜態修飾符,通常用來修飾類中的成員。dom

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修飾的成員能夠而且建議經過類名直接訪問。訪問靜態成員的格式:this

  • 類名.靜態成員變量名
  • 類名.靜態成員方法名(參數)
  • 對象名.靜態成員變量名 ------不建議使用該方式,會出現警告
  • 對象名.靜態成員方法名(參數) ------不建議使用該方式,會出現警告
複製代碼
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();
    }
}
複製代碼

static注意事項

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

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

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

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

main方法爲靜態方法僅僅爲程序執行入口,它不屬於任何一個對象,能夠定義在任意類中。對象

定義靜態常量

開發中,咱們想在類中定義一個靜態常量,一般使用public static final修飾的變量來完成定義。此時變量名用所有大寫,多個單詞使用下劃線鏈接。
定義格式: public static final 數據類型 變量名 = 值; blog

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

匿名對象

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

複製代碼
public class Person{
    public void eat(){
        System.out.println();
    }
}

//建立一個普通對象
Person p = new Person();
//建立一個匿名對象
new Person();
複製代碼

匿名對象的特色:

建立匿名對象直接使用,沒有變量名。

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());
    }
}
複製代碼

內部類

將類寫在其餘類的內部,能夠寫在其餘類的成員位置和局部位置,這時寫在其餘類內部的類就稱爲內部類。其餘類也稱爲外部類。
何時使用內部類?在描述事物時,若一個事物內部還包含其餘可能包含的事物,好比在描述汽車時,汽車中還包含這發動機,這時發動機就可使用內部類來描述。

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

內部類的分類

內部類分爲成員內部類與局部內部類。
定義內部類時,就是一個正常定義類的過程,一樣包含各類修飾符、繼承與實現關係等。在內部類中能夠直接訪問外部類的全部成員。
成員內部類,定義在外部類中的成員位置。與類中的成員變量類似,可經過外部類對象進行訪問
定義格式:

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();
    }
複製代碼

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

定義格式:

複製代碼
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();
    }
複製代碼

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

內部類是爲了應對更爲複雜的類間關係。查看源代碼中會涉及到,而在平常業務中很難遇到,這裏不作贅述。最經常使用到的內部類就是匿名內部類,它是局部內部類的一種。
定義的匿名內部類有兩個含義:

  • 臨時定義某一指定類型的子類
  • 定義後即刻建立剛剛定義的這個子類的對象

定義匿名內部類的做用與格式
做用:匿名內部類是建立某個類型子類對象的快捷方式。
格式:

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();

包的聲明與訪問

java的包,其實就是咱們電腦系統中的文件夾,包裏存放的是類文件。當類文件不少的時候,一般咱們會採用多個包進行存放管理他們,這種方式稱爲分包管理。
在項目中,咱們將相同功能的類放到一個包中,方便管理。而且平常項目的分工也是以包做爲邊界。
類中聲明的包必須與實際class文件所在的文件夾狀況相一致,即類聲明在a包下,則生成的.class文件必須在a文件夾下,不然,程序運行時會找不到類。

包的聲明格式

一般使用公司網址反寫,能夠有多層包,包名採用所有小寫字母,多層包之間用」.」鏈接。
類中包的聲明格式:  package 包名.包名.包名…; 
如:黑馬程序員網址itheima.com,那麼網址反寫就爲com.itheima
注意:聲明包的語句,必須寫在程序有效代碼的第一行(註釋不算)
代碼演示:

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

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

public class Demo {}

包的訪問

在訪問類時,爲了可以找到該類,必須使用含有包名的類全名(包名.類名)。 包名.包名….類名 ,如: java.util.Scanner
帶有包的類,建立對象格式: 包名.類名 變量名 = new包名.類名(); 好比cn.itcast.Demo d = new cn.itcast.Demo();
前提:包的訪問與訪問權限密切相關,這裏以通常狀況來講,即類用public修飾的狀況。

類的簡化訪問

當咱們要使用一個類時,這個類與當前程序在同一個包中(即同一個文件夾中),或者這個類是java.lang包中的類時一般能夠省略掉包名,直接使用該類。
當咱們要使用的類,與當前程序不在同一個包中(即不一樣文件夾中),要訪問的類必須用public修飾纔可訪問。

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包名.包名.類名;

訪問修飾符

在Java中提供了四種訪問權限,使用不一樣的訪問權限時,被修飾的內容會有不一樣的訪問權限,如下表來講明不一樣權限的訪問能力:

 

public

protected

default

private

同一類中

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

 

不一樣包的子類

 

 

不一樣包中的無關類

 

 

 

概括總結:

  • 要想僅能在本類中訪問使用private修飾;
  • 要想本包中的類均可以訪問不加修飾符便可;
  • 要想本包中的類與其餘包中的子類能夠訪問使用protected修飾
  • 要想全部包中的全部類均可以訪問使用public修飾。
  • 注意:若是類用public修飾,則類名必須與文件名相同。一個文件中只能有一個public修飾的類。

代碼塊

局部代碼塊:局部代碼塊是定義在方法或語句中。
特色:

  • 以」{}」劃定的代碼區域,此時只須要關注做用域的不一樣便可
  • 方法和類都是以代碼塊的方式劃定邊界的
複製代碼
class Demo{
    public static void main(String[] args) {
        {
            int x = 1;
            System.out.println("普通代碼塊" + x);
        }
        int x = 99;
        System.out.println("代碼塊以外" + x);
    }
}
複製代碼

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

特色:

  • 優先於構造方法執行,構造代碼塊用於執行全部對象均須要的初始化動做
  • 每建立一個對象均會執行一次構造代碼塊。
複製代碼
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);
    }
}
複製代碼

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

特色:
它優先於主方法執行、優先於構造代碼塊執行,當以任意形式第一次使用到該類時執行。
該類無論建立多少對象,靜態代碼塊只執行一次。
可用於給靜態變量賦值,用來給類進行初始化。

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

知識點總結

一、final:關鍵字,最終的意思

  • final修飾的類:最終的類,不能被繼承
  • final修飾的變量: 至關因而一個常量, 在編譯生產.class文件後,該變量變爲常量值
  • final修飾的方法: 最終的方法,子類不能重寫,能夠繼承過來使用

二、static : 關鍵字, 靜態的意思

  • 能夠用來修飾類中的成員(成員變量,成員方法)
  • 也能夠用來修飾成員內部類

特色:

  • 被靜態所修飾的成員,會被全部的對象所共享
  • 被靜態所修飾的成員,能夠經過類名直接調用,方便
Person.country = "中國";
Person.method();

注意事項:

  • 靜態的成員,隨着類的加載而加載,優先於對象存在
  • 在靜態方法中,沒有this關鍵字
  • 靜態方法中,只能調用靜態的成員(靜態成員變量,靜態成員方法

三、匿名對象:一個沒有名字的對象
特色:

  • 建立匿名對象直接使用,沒有變量名
  • 匿名對象在沒有指定其引用變量時,只能使用一次
  • 匿名對象能夠做爲方法接收的參數、方法返回值使用

四、內部類:在一個類中,定義了一個新類,這個新的類就是內部類

class A {//外部類
    class B{// 內部類
    }
}

特色: 內部類能夠直接訪問外部類的成員,包含私有的成員

五、包的聲明與訪問
類中包的聲明格式: package 包名.包名.包名…;
帶有包的類,建立對象格式:包名.類名 變量名 = new包名.類名();
六、導包的格式:import 包名.類名;

七、權限修飾符

  • public : 公共的
  • protected: 受保護的
  • private : 私有的
  • public protected 默認的 private

八、代碼塊:

  • 局部代碼塊:定義在方法中的,用來限制變量的做用範圍
  • 構造代碼塊:定義在類中方法外,用來給對象中的成員初始化賦值
  • 靜態代碼塊:定義在類中方法外,用來給類的靜態成員初始化賦值
相關文章
相關標籤/搜索