首頁  >  文章  >  Java  >  04.Java 基礎 - 類

04.Java 基礎 - 類

黄舟
黄舟原創
2017-02-27 10:20:121636瀏覽

基本概念

在物件導向的概念中,我們知道所有的物件都是透過類別來描繪的。

在 Java 中類別透過關鍵字 class 來定義。

同樣的在 Java 中類別具有多種形式,包括普通類別、抽象類別、內部類別。

其中內部類別又包含了:成員內部類別、局部內部類別、匿名內部類別、靜態內部類別。


普通類別

這個沒什麼好說的。

public class Demo { }

抽象類別

1.基本概念

上面提到所有的物件都是透過類別來描繪的,但是並不是所有的類別都是用來描繪物件的。

如果一個類別中沒有包含足夠的資訊來描繪一個具體的物件(我們可以理解為一種功能不全的類別),這樣的類別就是抽象類別

抽象類別透過關鍵字 absract 定義。它可以包含抽象方法、非抽象方法。


2.實例探究

  • #抽象類別定義

  • ##
    public abstract class Parent {
    
        // 1.成员变量,与普通类无差别
        private  String word="aa";    // 2.非抽象方法,与普通类无差
        private void talk(){
            System.out.println("Parent is talking");
        }    // 3.抽象方法,访问权限只能是 public 和 protected 
        abstract void print();
    }
  • 抽象類別繼承

  • // 1.抽象类继承抽象类,抽象子类不用实现父类的方法public abstract class Son extends Parent { }
    // 2.普通类继承抽象类,普通子类必须实现父类的所有抽象方法public class Grandson extends Son {
        @Override
        void print() {
            System.out.println("I am Grandson");
        }
    }
  • 抽象類別呼叫

##

// 错误,抽象类不允许被实例化//Parent parent = new Parent();

透過以上的程式碼,我們可以總結出這麼幾點:
  • #抽象類別、抽象方法,不能被private 修飾,而且必須使用關鍵字abstract 定義。
  • 子類別如果不是抽象類,則必須實作父類別所有的抽象方法。
  • 抽象類別不允許被實例化,編譯錯誤。
  • 抽象類別裡面也可以包含普通方法,成員變數。

成員內部類別

#1.基本概念

位於一個類別內部的類,稱為成員內部類別。

成員內部類別具有以下特點:可以存取其外圍類別的所有屬性,而不需要任何特殊條件。

2.實例探究

  • 成員內部類別定義:
    public class Outter {
        private int a = 10;    static int b = 20;    int c = 30;    // 内部类
        class Inner {        void print(int d) {
                System.out.println(a + "-" +b+ "-" +c+ "-" + "-" +d;
            }
        }    // 取得内部类
        Inner getInner() {        return new Inner();
        }
    }
  • 成員內部類別呼叫

Outter out = new Outter();// 创建内部类的两种方式:
Outter.Inner inner = out.new Inner();Outter.Inner inner2 = out.getInner();inner.print(20);
3.原理分析

透過反編譯class 文件,指令如下:

javap -v Outter

執行指令後,後來得到兩個class 檔:Outter.Class 和Outter$Inner.Class。

說明對虛擬機器來說,內部類別其實與常規類別是一樣的。所以 Inner 仍然被編譯成一個獨立的類別,而不是 Outter 類別的某一個領域。

但是由於成員內部類別看起來像是外部類別的一個成員,所以可以擁有與成員一樣的存取權限。

局部內部類別

1.基本概念

局部內部類別有兩種:
  • 方法內的類別。
  • 作用域內的類別。

可以將其視為方法或作用域的內局部變量,因此它的存取權限也僅限於方法內或該作用域內。

同局部變數一樣,它是無法被 public、protected、private、static 關鍵字修飾的。

2.實例探究


public class Man {
    public Object getWoman() {        // 注意:三个变量都相互不受影响
        int age = 30;        // 1.方法内的类
        class Woman {            int age = 20;
        }        // 2.作用域内的类,此时作用域为 if 
        if(true){
            class Son{                int age = 10;
            }
        }   
        return new Woman();
    }
}

#匿名內部類別

1.基本概念

匿名內部類別是唯一沒有建構器的類別。因為這個特點,匿名內部類別的使用範圍非常有限,大部分用於介面回呼

它有以下特點:
  • 匿名內部類別在編譯的時候由系統自動命名為 Outter$1.class。
  • 匿名內部類別一般用於繼承其他類別或是實作接口,並不需要增加額外的方法,只是對繼承方法的實作或重寫。
  • 匿名內部類別不能存取外部類別方法中的局部變數

    ,除非變數被宣告為final 類型

2.實例探究


public class Test {
    // a 属于全局变量
    int a =100;    public static void main(String[] args) {
        Test t = new Test();
        t.test(200);
    }    // b 属于局部变量
    public void test(final int b) {        // c 属于局部变量
        final int c = 300;        //  匿名内部类
        new Thread() {            int  d = 400;            public void run() {
                System.out.println(a+"-"+b+"-"+c+"-"+d);
            };
        }.start();
    }
}

3.原理分析

透過反編譯指令可以得到兩個class 檔: Outter.class 和Outter$1.class。

關於局部變數的生命週期:
  • 當方法被呼叫時,局部變數在堆疊中被創建。當方法運行結束後,退棧,局部變數死亡。

關於內部類別物件的宣告週期:
  • #建立一個匿名內部類別對象,系統為該物件分配內存,直到沒有引用變數指向分配給該物件的內存,它才會被GC 處理。

因此存在情況:
  • 成員方法已被呼叫結束,局部變數已死亡,但匿名內部類別的物件仍然活著。

所以在 Java 中採用了 final 關鍵字+複製的方法來解決:###
  • final 关键字:因为它的特性是一旦变量被赋值后,就不能被修改。

  • 复制:在匿名内部类中直接复制了一个与局部变量值的数,让它变成自己的局部变量。

所以当局部变量的生命周期结束后,匿名内部类照样可以访问 final 类型的局部变量,因为它自己拷贝了一份,且与原局部变量的值始终一致。

下面针对上面的代码来分析:

  • 当 test 方法执行完毕之后,变量 b、c 的生命周期就结束了。然而 Thread 对象的生命周期很可能还没有结束。因此要将 b、c 设置为 final 。

  • a 之所以不采用 final 修饰,因为它是全局变量,生命周期是随着类的结束而结束。而类的生命周期肯定大于匿名内部类。


静态内部类

1.基本概念

静态内部类也是定义在一个类里面的类,只不过在类的前面多了一个关键字static

静态内部类和静态成员变量其实具有相同的特点:

  • 它只有类有关,与对象无关。因此可以在没有外部类对象情况下,创建静态内部类。

  • 不能访问外部类的非静态成员或方法


2.实例探究

  • 内部静态类定义:

public class Outter {
    int a = 5;    static int b = 500;    // 静态内部类
    static class Inner {        public Inner() {            // 只能访问外部类的静态成员
            System.out.println(b);
        }
    }
}
  • 静态内部类调用:

// 静态内部类的调用不依赖外部类对象Outter.Inner inner= new Outter.Inner();

接口内部类

1.基本概念

接口内部类,顾名思义就是在接口内定义的类。


2.实例探究

  • 接口内部类定义:

public interface People{
    class Man {        public void print() {
            System.out.println("man.print()...");
        }
    }
}
  • 接口内部类调用:

People.Man  man = new People.Man();

 以上就是04.Java 基础 - 类的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn