1. 程式人生 > >Java面向對象(static、final、匿名對象、內部類、包、修飾符、代碼塊)

Java面向對象(static、final、匿名對象、內部類、包、修飾符、代碼塊)

固定 介紹 常量 屬於 權限 功能 復雜 art 代碼區

面向對象

今日內容介紹

u final

u static

u 匿名對象

u 內部類

u 包的聲明與訪問

u 四種訪問修飾符

u 代碼塊

第1章 final關鍵字

1.1 final的概念

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

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

1.2 final的特點

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

class Yy {}

final class Fu extends Yy{} //可以繼承Yy

class Zi extends Fu{} //不能繼承Fu

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

class Fu {

// final修飾的方法,不可以被覆蓋,但可以繼承使用

public final void method1(){}

public void method2(){}

}

class Zi extends Fu {

//重寫method2方法

public final void method2(){}

}

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

final int i = 20;

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

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

final Person p = new Person();

Person p2 = new Person();

p = p2; //final修飾的變量p,所記錄的地址值不能改變

p.name = "小明";//可以更改p對象中name屬性值

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

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

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特點

l 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

}

}

l 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註意事項

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

class Demo {

//成員變量

public int num = 100;

//靜態方法

public static void method(){

//this.num; 不能使用this/super

System.out.println(this.num);

}

}

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

class Demo {

//成員變量

public int num = 100;

//靜態成員變量

public static int count = 200;

//靜態方法

public static void method(){

//System.out.println(num); 靜態方法中,只能訪問靜態成員變量或靜態成員方法

System.out.println(count);

}

}

l 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(); // 調用一個靜態方法

l 註意:

接口中的每個成員變量都默認使用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 匿名對象的特點

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

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

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

new Person().eat(); 創建一個匿名對象,調用eat方法

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

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

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 內部類概念

l 什麽是內部類

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

l 什麽時候使用內部類

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

class 汽車 { //外部類

class 發動機 { //內部類

}

}

l 內部類的分類

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

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

4.2 成員內部類

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

l 定義格式

class 外部類 {

修飾符 class 內部類 {

//其他代碼

}

}

l 訪問方式

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

l 成員內部類代碼演示

定義類

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 局部內部類

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

l 定義格式

class 外部類 {

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

class 內部類 {

//其他代碼

}

}

}

l 訪問方式

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

l 局部內部類代碼演示

定義類

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 匿名內部類概念

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

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

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

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

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

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

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

格式:

new 父類或接口(){

//進行方法重寫

};

l 代碼演示

//已經存在的父類:

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

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

l 代碼演示:

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

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

l 類的簡化訪問

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

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

類名 變量名 = new類名();

Person p = new Person();

l 當我們要使用的類,與當前程序不在同一個包中(即不同文件夾中),要訪問的類必須用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);

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

第6章 訪問修飾符

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

public

protected

default

private

同一類中

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

不同包的子類

不同包中的無關類

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

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

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

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

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

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

第7章 代碼塊

7.1 局部代碼塊

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

特點:

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

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

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 構造代碼塊

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

特點:

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

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

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("Personage)參數的構造函數執行");

}

}

class PersonDemo{

public static void main(String[] args) {

Person p = new Person();

Person p1 = new Person(23);

}

}

7.3 靜態代碼塊

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

特點:

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

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

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

public class Person {

private String name;

private int age;

//靜態代碼塊

static{

System.out.println("靜態代碼塊執行了");

}

}

第8章 總結

8.1 知識點總結

l final:關鍵字,最終的意思

final修飾的類:最終的類,不能被繼承

final修飾的變量: 相當於是一個常量, 在編譯生產.class文件後,該變量變為常量值

final修飾的方法: 最終的方法,子類不能重寫,可以繼承過來使用

l static : 關鍵字, 靜態的意思

可以用來修飾類中的成員(成員變量,成員方法)

註意: 也可以用來修飾成員內部類

l 特點:

被靜態所修飾的成員,會被所有的對象所共享

被靜態所修飾的成員,可以通過類名直接調用,方便

Person.country = "中國";

Person.method();

l 註意事項:

靜態的成員,隨著類的加載而加載,優先於對象存在

在靜態方法中,沒有this關鍵字

靜態方法中,只能調用靜態的成員(靜態成員變量,靜態成員方法

l 匿名對象:一個沒有名字的對象

l 特點:

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

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

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

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

class A {//外部類

class B{// 內部類

}

}

l 特點:

內部類可以直接訪問外部類的成員,包含私有的成員

l 包的聲明與訪問

l 類中包的聲明格式:

package 包名.包名.包名…;

l 帶有包的類,創建對象格式:包名.類名 變量名 = new包名.類名();

cn.itcast.Demo d = new cn.itcast.Demo();

l 導包的格式:

import 包名.類名;

l 權限修飾符

public : 公共的

protected: 受保護的

private : 私有的

public protected 默認的 private

在當前類中 Y Y Y Y

同一包中的其他類 Y Y Y

不同包中的子類 Y Y

不同包中的其他類 Y

l 代碼塊:

局部代碼塊:定義在方法中的,用來限制變量的作用範圍

構造代碼塊:定義在類中方法外,用來給對象中的成員初始化賦值

靜態代碼塊:定義在類中方法外,用來給類的靜態成員初始化賦值

Java面向對象(static、final、匿名對象、內部類、包、修飾符、代碼塊)