選擇器優先順序
阿新 • • 發佈:2021-06-30
1.內部類
概述:
把類定義在其他類的內部,這個類就被稱為內部類。
舉例:在類A中定義了一個類B,類B就是內部類。
內部類位置:
- 成員位置(成員內部類)
- 區域性位置(區域性內部類)
內部類的種類:
- 成員內部類 ----成員變數
- 靜態成員內部類 --靜態成員變數
- 區域性內部類--區域性變數
- 匿名內部類
內部類的訪問特點:
1、內部類可以直接訪問外部類的成員,包括私有。
2、外部類要訪問內部類的成員,必須建立物件。
2.成員內部類
- 外界如何建立內部類物件?
外部類名.內部類名 物件名 = 外部類物件.內部類物件;
外部類名.內部類名 inner = new 外部類().new 內部類();
- 成員內部類的修飾符 ---> 成員變數
基本上成員變數和成員方法能用的修飾符成員內部類都可以用
例如:四種許可權修飾符、static、final、abstracter
- 成員內部類的常見修飾符
- 程式碼:
class Demo1_InnerClass {
public static void main(String[] args) {
//Inner i = new Inner();
//i.method();
//外部類名.內部類名 = 外部類物件.內部類物件
Outer.Inner oi = new Outer().new Inner(); //建立內部類物件
oi.method();
}
}
class Outer {
private int num = 10;
class Inner {
public void method() {
System.out.println(num);
}
}
}
3.區域性內部類
可以直接訪問外部類的成員
可以建立內部類物件,通過物件呼叫內部類方法,來使用區域性內部類功能
- 區域性內部類如何使用內部類建立物件?
直接在成員方法內部位置建立該內部類物件並使用
區域性內部類訪問區域性變數的注意事項:
必須被final修飾 !
為什麼?
因為區域性變數會隨著方法的呼叫完畢而消失,這個時候,區域性物件並沒有立馬從堆記憶體中消失,還要使用那個變數。為了讓資料還能繼續被使用,就用fianl修飾,這樣,在堆記憶體裡面儲存的其實是一個常量值。
程式碼:
class Demo1_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
//區域性內部類
class Outer {
public void method() {
final int num = 10;
class Inner {
public void print() {
System.out.println(num);
}
}
Inner i = new Inner();
i.print();
}
/*public void run() {
Inner i = new Inner(); //區域性內部類,只能在其所在的方法中訪問
i.print();
}*/
}
4.靜態內部類
- 成員內部類被static修飾後外界如何建立物件
外部類類名物件名= new外部類名.內部類名();
外部類名.內部類名 inner3 = new 外部類.內部類();
程式碼:
class Demo1_InnerClass {
public static void main(String[] args) {
//外部類名.內部類名 物件名 = 外部類名.內部類物件;
Outer.Inner oi = new Outer.Inner();
oi.method();
Outer.Inner2.print();
}
}
class Outer {
static class Inner {
public void method() {
System.out.println("method");
}
}
static class Inner2 {
public static void print() {
System.out.println("print");
}
}
}
5.匿名內部類
匿名內部類就是內部類的簡化寫法。其本質是一個繼承了類或者實現了介面的子類匿名物件。
使用前提:存在一個類或者介面(這裡的類可以是具體類也可以是抽象類)。
本質:匿名內部類是一個介面或者抽象類的實現類或者子類的物件!
格式:
new 類名或者介面名() {
重寫方法;
}
匿名內部類在開發中的使用
首先回顧我們曾經講過的方法的形式引數是引用型別的情況,重點是介面的情況,我們知道這裡需要一個子類物件。而匿名內部類就是一個子類匿名物件,所以,可以使用匿名內部類改進以前的做法。
程式碼:
public class Test2 {
public static void main(String[] args) {
//多型
// A a = new B();
// a.method();
//使用A介面的匿名內部類
//建立匿名內部類物件
A a = new A() {
@Override
public void method() {
System.out.println("匿名內部類");
}
};
a.method(); // 匿名內部類
//匿名內部類的形式建立抽象類物件
C c = new C() {
@Override
public void method() {
System.out.println("抽象類物件");
}
};
c.method(); //抽象類物件
method(a); //匿名內部類
method(new A() {
@Override
public void method() {
System.out.println("A");
}
}); //A
}
public static void method(A a) {
a.method();
}
}
interface A {
public void method();
}
class B implements A {
@Override
public void method() {
System.out.println("b");
}
}
abstract class C {
public abstract void method();
}
程式碼:
class Test1_NoNameInnerClass {
public static void main(String[] args) {
//如何呼叫PersonDemo中的method方法呢?
PersonDemo pd = new PersonDemo ();
//pd.method(new Student());
pd.method(new Person() {
public void show() {
System.out.println("show");
}
});
}
}
//這裡寫抽象類,介面都行
abstract class Person {
public abstract void show();
}
class PersonDemo {
//public void method(Person p) { //Person p = new Student(); //父類引用指向子類物件
/*
Person p = new Person(){
public void show() {
System.out.println("show");
}
};
*/
public void method(Person p) {
p.show();
}
}
class Student extends Person {
public void show() {
System.out.println("show");
}
}
5.內部類的作用
1、隱藏類的實現細節
2、可以無條件的訪問外部類的成員
3、過內部類可以實現多重繼承
在內部類中,當成員內部類的成員變數或成員方法和外部類同名時該如何訪問?
1、訪問內部類的成員變數和成員方法
2、訪問外部類的成員變數和成員方法
程式碼:
package com.southwind.test;
/**
* 內部類的位置:
* 內部類的訪問---內部類造物件
* 成員內部類造物件
*
* 內部類可以沒有任何條件的訪問外部類的成員
*/
class Outer {
private int num = 10;
public void method2(){
System.out.println("method2...");
//外部類中訪問內部類中的成員
//必須建立內部類物件
//成員內部類物件如何建立
Inner inner = new Inner();
System.out.println(inner.i);
Inner3 inner3 = new Inner3();
}
public static int num2;
//靜態內部類
public static class Inner3 {
public void method(){
//靜態的成員不能訪問非靜態的
// System.out.println(num);
// method2();
}
}
//成員內部類---成員位置
public class Inner {
int i = 1;
public void method(){
System.out.println(num);
method2();
}
}
public void method() {
// int num;
//區域性內部類
class Inner2 {
public void method(){
System.out.println(num);
method2();
}
}
//區域性內部類只能在區域性範圍內使用
Inner2 inner2 = new Inner2();
inner2.method();
}
}
public class Test {
public static void main(String[] args) {
//建立外部類物件,都是在外部類外部
//成員內部類造物件
Outer.Inner inner = new Outer().new Inner();
//格式:外部類名.內部類名 inner = new 外部類().new 內部類();
inner.method();
// System.out.println(inner.i);
//靜態內部類造物件
Outer.Inner3 inner3 = new Outer.Inner3();
//格式:外部類名.內部類名 inner3 = new 外部類.內部類();
//建立外部類物件
//呼叫方法
//執行區域性內部類物件的方法
Outer outer = new Outer();
outer.method();
}
}