1. 程式人生 > >8、構造方法&匿名內部類&許可權

8、構造方法&匿名內部類&許可權

1、構造方法

概念及功能:用來建立例項物件的方法, 給物件的資料進行初始化 。Person p = new Person(); 呼叫構造方法 Person()只是我們沒有寫這個方法,而是Java自動補齊了這個方法,是方法就可以傳入引數。建立物件時,可以直接為成員變數賦值,無需再在物件產生後再賦值。

格式:一般定義在其他方法前,成員變數後。沒有返回值型別定義,方法名與類名相同,引數依據需求而定。

注意:構造方法是必須存在的,如果沒有手動給出構造方法 ,java會為我們自動補齊一個空參的構造方法。如果手動給出任意構造方法 java將不會為我們補齊空參構造。修飾符:public 代表公共的 ,任何包下都可以訪問。 預設什麼都不寫代表預設許可權,當前包下可以訪問。private代表私有,本類中可以訪問。空參構造是習慣上存在的,帶參的構造方法通常是為了給屬性賦值的。構造方法不能被繼承。介面沒有構造方法,抽象類具有構造方法。

繼承關係中的構造方法:在每次建立子類物件時,我們均會先建立父類物件,再建立其子類物件本身。目的在於子類物件中包含了其對應的父類物件,便可以包含其父類物件的成員,如果父類成員非private修飾,則子類可以隨意使用父類成員。反之,如果沒有先建立父類物件就使用了子類物件,則子類無法使用父類的成員。抽象類包含構造方法的原因就在於其僅僅是為了給成員變數賦值,供子類使用。這裡我們需要注意的是,記憶體當中實際是存在抽象類的物件空間的,我們無法直接建立抽象類物件,但是子類可以,在子類的記憶體空間中包括了這個抽象父類物件。

super關鍵字:super代表本類物件中包含的父類物件空間的引用。在子類的任意位置,均可以使用super.屬性名或者super.方法名()的方式訪問父類空間的非私有成員。在子類的每個構造方法中,第一行具有預設呼叫父類空參構造程式碼,即super().所以在每次建立子類物件時,會先建立父類的構造。使用super(引數)可以訪問父類任意引數的構造,當手動呼叫父類任意的構造方法後,Java將不再提供預設呼叫父類空參的構造方法。

this呼叫本類其他構造:使用this(引數)可以訪問子類任意其他引數的構造方法,當手動呼叫子類任意的構造方法後,Java將不再提供預設呼叫父類空參的構造方法。this呼叫構造方法與super呼叫構造方法不能同時出現。無論以哪種方式完成構造方法的定義,均會先建立父類物件,再建立子類物件。

public class Test {
	public static void main(String[] args) {
	Student a=new Student();
	System.out.println(a.name);//人類
	Student b=new Student("高手");
	System.
out.println(b.name);//高手 } } class Person{ public String name="人類"; } class Student extends Person{ public String name; public Student(){this.name=super.name;} public Student(String s){//定義帶參構造一般都是為了給成員變數賦值 this();//呼叫本類無參空構造方法 this.name=s;//此局沒有則會把name賦值為父變數的name } }

變數訪問的就近原則:當多個位置出現相同名稱的變數時,訪問時會根據就近原則依次訪問。其先後順序為:區域性位置>本類成員位置>父類成員位置 >父類的父類成員位置 …

public class Test {
	public static void main(String[] args) {
	Student a=new Student();
	a.findName();//現在區域性變數找name,沒有定義則在本類找,否則就在父類……本例列印高手
	}
}
	class Person{
	public String name="人類";
	}
	class Student extends Person{
	public String name="學生";
	public void findName(){
	public String name="高手";
	System.out.println(name);}
	}

2、關鍵字

final:些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。要解決上述的這些問題,需要使用到一個關鍵字final,final的意思為最終,不可變。final是個修飾符,它可以用來修飾類,類的成員,以及區域性變數。

☆ 特點:final修飾類不可以被繼承,但是可以繼承其他類。final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋後可以加final。final修飾的變數稱為常量,這些變數只能賦值一次。引用型別的變數值為物件地址值,地址值不能更改,但是地址內的物件屬性值可以修改。修飾成員變數,需要在建立物件前賦值,否則報錯。(當沒有顯式賦值時,多個構造方法的均需要為其賦值。)

class Person{
	final int n;//final修飾的成員變數,需要在建立物件前賦值,否則報錯。但可以在建立物件時所呼叫的構造方法中,為變數n賦值
	public Person(){n=2;}
}

static:被static修飾的成員可以並且建議通過類名直接訪問。也可以通過某個物件訪問到屬於類的靜態成員,多個物件共享使用同一個靜態成員。

☆ 特點:static是靜態修飾符,一般修飾成員。被static修飾的成員屬於類,不屬於單個這個類的某個物件。static修飾的成員被多個物件共享。static修飾的成員屬於類,但是會影響每一個物件。被static修飾的成員又叫類成員,不叫物件的成員。靜態內容是優先於物件存在,只能訪問靜態,不能使用this/super。靜態修飾的內容存於靜態區。同一個類中,靜態成員只能訪問靜態成員。main方法為靜態方法僅僅為程式入口,不屬於任何一個物件,所以可以定義在任意類中。

☆ 通常使用public static final來修飾某個類中的靜態常量。此時識別符號用全部大寫,多個單詞使用下劃線連線。

public class Test {
	public static void main(String[] args) {
	Person a=new Person();
	System.out.println(a.ADDRESS);//物件名.靜態成員------不建議,出現警告應該用Person.ADDRESS
	a.method();
	}
}
	class Person {//靜態內容是優先於物件存在,只能訪問靜態,不能使用this/super。靜態修飾的內容存於靜態區。
	static int age;//被static修飾的成員屬於類,不屬於單個這個類的某個物件。
	public static final String ADDRESS ="中國";
	public static void method(){
	System.out.println(age);//不能使用this.age
	//System.out.println(name);靜態只能訪問靜態 不能用已存在的去訪問還沒出現的,靜態內容優於物件存在
	}
}

3、匿名物件與內部類

匿名物件 ☆概念:匿名物件是指建立物件時,只有建立物件的語句,卻沒有把物件地址值賦值給某個變數。建立一個普通物件:Person p = new Person();建立一個匿名物件:new Person();。

☆特點:建立匿名物件直接使用,沒有變數名。匿名物件在沒有指定其引用變數時,只能使用一次。匿名物件可以作為方法接收的引數、方法返回值使用(使用可以在任意位置)

內部類: ☆概念:將類寫在其他類的內部,可以寫在其他類的成員位置和區域性位置,這時寫在其他類內部的類就稱為內部類。其他類也稱為外部類。內部類分為成員內部類與區域性內部類。

成員內部類

//定義格式
修飾符 class 外部類 {
修飾符 class 內部類 {//其他程式碼}
//其他程式碼}
*********************
//訪問方式
外部類名.內部類名 變數名 = new 外部類名().new 內部類名();

區域性內部類:

//定義格式
修飾符 class 外部類 {
修飾符 返回值型別 方法名(引數) {
修飾符 class 內部類 {//其他程式碼}}
}
//訪問方式
在外部類方法中,建立內部類物件,進行訪問

匿名內部類:

public class Test {
	public static void main(String[] args) {
	Person  p = new Person(){//定義並建立該父類的子類物件,並用多型的方式賦值給父類引用變數
	public void eat() {System.out.println(“我吃了”);}
	};
	p.eat();
	}
	//匿名內部類如果不定義變數引用,則也是匿名物件。
	//new Person(){
	//public void eat() {System.out.println(“我吃了”);}
	//}.eat();
}
public abstract class Person{
	public abstract void eat();
}

4、包

概念:java的包,其實就是我們電腦系統中的資料夾,包裡存放的是程式生成的.class檔案。當.class檔案很多的時候,通常我們會採用多個包進行存放管理他們,這種方式稱為分包管理,分包管理是組織軟體專案結構的基本方式。通常使用公司網址反寫,可以有多層包,包名採用全部小寫字母,多層包之間用”.”連線類中包的宣告格式。

訪問:在訪問類時,為了能夠找到該類,必須使用含有包名的類全名(包名.類名)。建立物件格式:包名.類名 變數名 = new包名.類名();當我們要使用一個類時,這個類與當前程式在同一個包中(即同一個資料夾中),或者這個類是java.lang包中的類時通常可以省略掉包名,直接使用該類。當我們要使用的類,與當前程式不在同一個包中(即不同資料夾中),要訪問的類必須用public修飾才可訪問。

導包:可以通過導包的方式使用該類,可以避免使用全類名編寫(即,包類.類名)。import導包程式碼書寫的位置:在宣告包package後,定義所有類class前,使用導包import包名.包名.類名;。

訪問許可權

public protected default private
同一類中
同一包中
不同包的子類
不同包中的無關類

要想僅能在本類中訪問使用private修飾;要想本包中的類都可以訪問不加修飾符即可;要想本包中的類與其他包中的子類可以訪問使用protected修飾;要想所有包中的所有類都可以訪問使用public修飾。如果類用public修飾,則類名必須與檔名相同。一個檔案中只能有一個public修飾的類。

class Person{
	public void method1(){System.out.println("公共方法");}
	protected void method2(){System.out.println("受保護的方法");}
	void method3(){System.out.println("預設許可權方法");}
	private  void method4(){System.out.println("私有方法");}
	public void method(){method1();method2();method3();method4();}
}
public class Test {//同一類中
	public static void main(String[] args) {
	Person p = new Person();
	p.method();//列印四種方法
	}
}
public class Test {//同一個包下子類或者無關類
	public static void main(String[] args) {
	Person p = new Person();
	//p.method4();不會列印
	}
}
public class Test {//不同包下的子類
	public static void main(String[] args) {
	Person p = new Person();
	//p.method3();不會列印
	//p.method4();不會列印
	}
}
public class Test {//不同包下的無關類
	public static void main(String[] args) {
	Person p = new Person();
	//p.method2();不會列印
	//p.method3();不會列印
	//p.method4();不會列印
	}
}

程式碼塊:區域性程式碼塊:普通程式碼塊就是直接定義在方法或語句中,以”{}”劃定的程式碼區域,此時只需要關注作用域的不同即可,方法和類都是以程式碼塊的方式劃定邊界的。構造程式碼塊:又叫成員程式碼塊,直接定義在類中成員位置的程式碼塊,優先於構造方法執行,構造程式碼塊用於執行所有物件均需要的初始化動作,每建立一個物件均會執行一次構造程式碼塊。靜態程式碼塊:靜態程式碼塊是定義在成員位置,使用static修飾的程式碼塊,它優先於主方法執行、優先於構造程式碼塊執行,當以任意形式第一次使用到該類時執行。該類不管建立多少物件,靜態程式碼塊只執行一次。可用於給靜態變數賦值,用來給類進行初始化。