標籤:object return public java
在Java中,可以將一個類定義在另一個類裡面或者一個方法裡面,這樣的類稱為內部類。內部類仍然是一個獨立的類,在編譯之後內部類會被編譯成獨立的.class檔案,但是前面冠以外部類的類名和$符號。內部類可以間接解決多繼承問題,可以使用內部類繼承一個類,外部類繼承一個類,實現多繼承。
內部類主要分為成員內部類,方法內部類,靜態內部類,匿名內部類。
1.成員內部類
成員內部類顧名思義就是外部類的一個成員屬性,只不過該屬性不是String,int等類型,而是class類型。類的成員內部類可以訪問該類的屬性和方法,因為他也是該類的一個成員。
成員內部類使用:
-
package com.dream;
-
-
public class MyTest {
-
-
public static void main(String[] args) {
-
-
Mother mother=new Mother(12, "小明");
-
-
//執行個體內部類的方法之一
-
Mother.baby temp=mother.new baby();
-
temp.say();
-
-
//執行個體化方法二,通過調用類的成員函數訪問內部類
-
mother.say();
-
-
}
-
-
}
-
-
class Mother{
-
-
private int age;
-
-
public String name;
-
-
public Mother(int age, String name) {
-
-
this.age = age;
-
this.name = name;
-
}
-
-
//定義內部類(成員內部類)
-
class baby{
-
public void say()
-
{
-
System.out.println("我已經"+age+"歲啦,名字叫"+name);
-
}
-
}
-
-
//在類中執行個體化
-
public void say()
-
{
-
baby temp=new baby();
-
temp.say();
-
}
-
-
}
複製代碼
成員內部類是類的一個成員,類的成員依賴類對象,所以內部類也依賴於對象,類需要執行個體化才能使用,所以使用外部類對象來執行個體化內部類。
2.方法內部類
顧名思義方法內部類即把類定義在方法裡面,需要注意的是:
1.方法內部類只能在定義該內部類的方法裡執行個體化,不可在此方法之外地方對其執行個體化
2.方法內部類對象不能使用該內部類所在方法的非final屬性
-
public class MyTest {
-
public void say(final String name)
-
{ //方法內部類
-
class baby
-
{
-
public void say()
-
{
-
//需要final屬性
-
System.out.println("名字叫"+name);
-
}
-
-
}
-
-
//在該方法內部執行個體化
-
baby temp=new baby();
-
temp.say();
-
}
-
-
public static void main(String[] args) {
-
-
MyTest test=new MyTest();
-
test.say("王小帥");
-
-
}
-
-
}
複製代碼
方法內部類的範圍局限於該方法內,所以要在方法內執行個體化。方法內定義的變數是局部變數,離開該方法,變數就失去了作用,也就會自動被消除,而內部類卻不會離開它所在方法就失去作用,它有更廣的生命週期,所以需要拷貝到內部類中,而拷貝會帶來不一致性,從而需要使用final聲明保證一致性。
3.靜態內部類
即在一個類裡定義一個靜態內部類,靜態就是該內部類可以像其他靜態成員一樣,沒有執行個體的外部類對象也可以訪問調用,靜態屬性不屬於類的執行個體對象。
-
public class MyTest {
-
-
public int age=1;
-
-
public static String name="小黑";
-
//定義靜態內部類
-
static class baby{
-
-
public void say()
-
{
-
//不能訪問age屬性,只能訪問靜態屬性
-
System.out.println("name: "+name);
-
}
-
-
}
-
-
public static void main(String[] args) {
-
//執行個體化靜態內部類
-
MyTest.baby temp=new MyTest.baby();
-
temp.say();
-
}
-
-
}
-
複製代碼
需要注意的是靜態內部類只能訪問外部類中的靜態成員屬性和方法,因為靜態屬性可以不使用外部執行個體對象進行訪問,若屬性不是靜態屬性,則需要依賴於外部類的執行個體對象。所以靜態內部類只能訪問外部類的靜態屬性
4.匿名內部類
匿名內部類有點像匿名對象,沒有名字,只能使用一次,匿名內部類又分三種情況
1.繼承式匿名內部類:可以不定義class去繼承該抽象類別而實現抽象類別的執行個體和運行
-
public class MyTest {
-
-
public static void main(String[] args) {
-
-
//相當繼承Mother類並實現抽象方法
-
Mother mother=new Mother(25, "桂綸鎂"){
-
public void say()
-
{
-
System.out.println("age: "+age+" name: "+name);
-
}
-
};
-
mother.say();
-
-
}
-
-
}
-
-
abstract class Mother{
-
-
public int age;
-
-
public String name;
-
-
public Mother(int age, String name) {
-
-
this.age = age;
-
this.name = name;
-
}
-
-
public abstract void say();
-
}
複製代碼
2.介面式匿名內部類:可以不定義class去實現該介面而實現介面的調用
-
public class MyTest {
-
-
public static void main(String[] args) {
-
-
//相當於實現介面
-
baby temp=new baby() {
-
@Override
-
public void say() {
-
System.out.println("name: "+name);
-
}
-
};
-
temp.say();
-
-
}
-
-
}
-
-
interface baby{
-
-
String name="小黑";//介面定義的屬性都是常量,修飾為 public final static String name
-
public void say();
-
}
複製代碼
3.參數式匿名內部類:只能訪問final屬性
-
public class MyTest {
-
-
public void say(baby temp)
-
{
-
temp.say();
-
}
-
-
public static void main(String[] args) {
-
-
MyTest test=new MyTest();
-
-
final int age=10;
-
//參數匿名內部類
-
test.say(new baby() {
-
-
@Override
-
public void say() {
-
//要訪問final定義的屬性
-
System.out.println("age: "+age);
-
-
}
-
});
-
}
-
-
}
-
-
interface baby{
-
String name="小黑";//介面定義的屬性都是常量,修飾為 public final static String name
-
public void say();
-
}
複製代碼
說明為什麼要使用final屬性
主要是局部變數的生命週期與局部內部類的對象的生命週期的不一致。
內部類裡面使用外部類的局部變數時,其實就是內部類的對象在使用它,內部類對象生命週期中都可能調用它,而內部類試圖訪問外部方法中的局部變數時, 外部方法的局部變數很可能已經不存在了,那麼就得延續其生命,拷貝到內部類中,而拷貝會帶來不一致性,從而需要使用final聲明保證一致性。 複製保證生命週期延續,final保證引用一致。
java內部類