1. 程式人生 > 其它 >Java常用類(1)- 內部類

Java常用類(1)- 內部類

內部類的概念

概念:在一個類的內部再定義一個完整的類

特點:

//外部類Menber
public class Member {
    private String name;

    public static void main(String[] args) {
        new Member().new body().getName();
    }


    //內部類body
    class body{
        public void getName(){
            System.out.println(name);
        }
    }
}
  • 編譯之後可以生成獨立的位元組碼檔案
  • 內部類可直接訪問外部類的私有屬性,從而不破壞封裝
  • 可為外部類提供必要的內部功能元件

內部類的分類

成員內部類

  • 在類的內部定義,與例項變數、例項方法同級別的類
  • 外部類的一個例項部分,建立內部類物件時,必須依賴外部類物件
package commonclass.innerclass;

import java.lang.reflect.Method;

//外部類Menber
public class Member {

    //例項變數
    private String name;

    //內部類body
    public
class body{ //內部類方法 public void getName(){ System.out.println(name); } } }
import commonclass.innerclass.Member;

public class Application {
    public static void main(String[] args) {

        //呼叫內部類方法

        //方式一
        //1.建立外部類物件
        Member member = new
Member(); //2.建立內部類物件 Member.body body = member.new body(); //方式二 Member.body body1 = new Member().new body(); //方式三直接呼叫 new Member().new body().getName(); //3.呼叫內部類方法 body.getName();//方式一呼叫 body1.getName();//方式二呼叫 } }
  • 當外部類、內部類存在重名屬性時,會優先訪問內部類屬性
  • 當外部類、內部類存在重名屬性時,想要訪問外部類屬性怎麼辦?外部類.this.外部類屬性
  • 成員內部類不能定義靜態成員,但是可以定義靜態常量

靜態內部類

  • 不依賴外部類物件,可直接建立或通過類名訪問,可宣告靜態成員
  • 只能直接訪問外部類的靜態成員,訪問非靜態成員需要先例項化外部類,再訪問
  • 當外部類、靜態內部類存在重名靜態屬性時,想要訪問外部類屬性怎麼辦?外部類.外部類屬性
package commonclass.innerclass;

//外部類
public class StaticClass {
    static String name = "李四";
    static int age = 14;
    double score = 99.9;

    //靜態內部類,它的級別和外部類一樣;
    //靜態內部類存在的意義就是供外部類使用
    public static class Inner{

        //靜態成員
        static String name = "張三";
        public void getName(){
            StaticClass staticClass = new StaticClass();
            System.out.println(name);
            System.out.println(age);
            System.out.println(staticClass.score);
            System.out.println(staticClass.name);
            System.out.println(StaticClass.name);

        }
    }
}
import commonclass.innerclass.Member;
import commonclass.innerclass.StaticClass;

public class Application {
    public static void main(String[] args) {
        StaticClass.Inner inner = new StaticClass.Inner();
        inner.getName();
    }
}

區域性內部類

  • 定義在外部類方法中,作用範圍和建立物件範圍僅限於當前方法
  • 區域性內部類訪問外部類當前方法中的區域性變數時,因無法保障變數的生命週期與自動相當(簡單來講就是載入的方法和類載入的問題),方法中的變數必須為常量,jdk1.8之後預設在區域性內部類中,將變數設定為常量
  • 使用範圍只有在當前方法中使用
  • 區域性內部類方法,最後需要將區域性內部類例項化,在外部類的當前方法中呼叫。區域性內部類才有意義
//外部類
public class LocalClass {

    //外部類引數
    private String name = "張三";

     public void print(){
         //方法引數
         int age = 20;

         //區域性內部類
         class Inner{
             //區域性內部類引數
             double score = 99.9;

             //區域性內部類方法
             public void show(){
                 System.out.println(name);
                 System.out.println(age);
                 System.out.println(score);
             }
         }
         //例項化區域性內部類
         Inner inner = new Inner();
         //呼叫區域性內部類
         inner.show();
     }
}
import commonclass.innerclass.LocalClass;

public class Application {
    public static void main(String[] args) {
        //區域性內部類只需要new外部類即可,呼叫外部類的方法,從而實現呼叫方法中的區域性內部類
        LocalClass localClass = new LocalClass();
        localClass.print();
    }
}

匿名內部類

  • 沒有類名的區域性內部類(一切特徵都與區域性內部類相同),可有理解為匿名內部類是區域性內部類的簡寫方式
  • 匿名內部類存在的前提是必須繼承一個父類或者實現一個介面
  • 定義類、實現類、建立物件的語法合併,只能建立一個該類的物件
  • 優點:減少程式碼量
  • 缺點:可讀性比較差

前置

package commonclass.innerclass;

//介面
public interface UserService {
    void print();
}
package commonclass.innerclass;

//父類
public class Person {
    public void printFather(){
    }
}

區域性內部類重寫介面以及父類的方法

package commonclass.innerclass;

//外部類
public class AnonymousClass {

    //main方法
    public static void main(String[] args) {

        //區域性內部類-介面
        class UserServiceImp implements UserService{
            @Override
            public void print() {
                System.out.println("介面重寫");
            }
        }
        UserServiceImp userServiceImp = new UserServiceImp();
        userServiceImp.print();
        
        //區域性內部類-父類
        class Student extends Person{
            //Alt+Insert選擇Over.. Method重寫父類方法
            @Override
            public void printFather() {
                System.out.println("繼承父類,父類方法重寫");
                super.printFather();
            }
        }
        Student student = new Student();
        student.printFather();
    }
}

匿名內部類重寫介面以及父類的方法

package commonclass.innerclass;

//外部類
public class AnonymousClass {

    //main方法
    public static void main(String[] args) {

//匿名內部類-介面 UserService userService
= new UserService(){ @Override public void print() { System.out.println("匿名內部類重寫介面"); } }; userService.print();
//匿名內部類-父類 Person person
= new Person(){ @Override public void printFather() { System.out.println("匿名內部類重寫父類方法"); super.printFather(); } }; person.printFather(); } }

匿名內部類和區域性內部類的比較