内部类

一,内部类

  1.什么是内部内:

    如果定义在局部位置(方法中/代码块中):  1) 局部内部类   2)匿名内部类

    定义在成员位置 1)成员内部类  2)静态内部类

  2.基本介绍

    一个类的内部又完整的嵌套了另一个类结构,被嵌套的类成为内部类(inner class),嵌套其它类的类成为外部类(outer calss),是我们类的第五大成员

 类的五大成员:属性 ,方法,构造器,代码块,内部类,内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系,

    注意:内部类是学习的难点和重点,后面看底层源码时,会有大量的内部类

  3. 基本语法 :

    calss Outer{                     //外部类

      class Inner{    //内部类

      }          

    }      

    class Other {      //外部其它类

    }

public class InnerClass {  //外部类
    public static void main(String[] args) {
    }
}
class Outer1{
    public int num = 1;  // 1.属性
    public Outer1(int num) {   // 2.构造器
        this.num = num;
    }
    public void say(){    // 3.方法
        System.out.println("方法 say");
    }
    {
        System.out.println("代码块");  // 4.代码块
    }
    class Inner{}   // 5.内部类
}

  4.内部类的分类

    定义在外部类局部位置上 (比如方法内):

    1)局部内部类 (由类名)

    2)匿名内部类 (没有类名  重点)

    定义在外部类的成员位置上

    1)成员内部类 (没用static修饰)

    2)静态内部类 (使用static)修饰

二, 局部内部类的使用

  说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名

  1.可以直接访问外部类的所有成员,包含私有的

  2.不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的,但是可以使用final修饰,因为局部变量也可以使用final

  3.作用域: 仅仅在定义它的方法或代码块中。

  4,局部内部类----访问---->外部类的成员  【访问方式 :直接访问】

  5,外部类--------访问-------->局部内部类的成员

    访问方式: 创建对象,再访问(注意:必须在作用域内)

  记住:1)局部内部类定义在方法中/代码块中

      2)作用域在方法体或者代码块中

      3)本质仍然是一个类

  6,外部其它类-------不能访问-----> 局部内部类 (因为局部内部类地位是一个局部变量)

  7,如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

      System.out.print("外部类的n2=“ + 外部类名.this.成员);

三 , 匿名内部类

  1. 本质上是类    , 内部类   , 该类没有名字 , 同时还是个对象

  说明:匿名内部类是定义在外部的局部位置,比如方法,并且没有类名

    匿名内部类的基本语法

    new  类或接口 (参数列表){

      类体

    };

  2,基于接口的匿名内部类

    传统方式  ;基于接口 写一个类去实现这个接口 ,然后new 对象  ,如果实现类比较多而且只想用一次,每次去实现接口太麻烦,这就提到了匿名内部类

    

package com.atpig.inner;

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        outer1.method();
    }
}
class Outer1{  //外部类
    public int n1 = 10;  //属性
    public void method(){   ///方法
//        tiger tiger = new tiger();
//        tiger.cry();
        IA tiger = new IA(){
            @Override
            public void cry() {
                System.out.println("老虎再叫");
            }
        };
    }
}
interface IA{  //接口
   public void cry();
}
//class tiger implements IA{
//
//    @Override
//    public void cry() {
//        System.out.println("老虎在叫");
//    }
//}

    匿名内部类的底层会分配一个类名   匿名内部类使用一次,就不能再使用

    

class Outer04$1 implements IA {
    @Override
    public void cry() {
        System.out.println("老虎叫唤...");
    }
}
//======================================
IA tiger = new IA() {
    @Override
    public void cry() {
    System.out.println("老虎叫唤...");
    }
};    

 

  3.基于类的匿名内部类

   

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        outer1.method();
    }
}
class Outer1{  //外部类
    public int n1 = 10;  //属性
    public void method() {///方法
        //基于类的匿名内部类
        Father father = new Father("jack"){
            @Override
            public void test() {
                System.out.println("方法被调用可");
            }
        };
        System.out.println(false);
        father.test();
        //基于抽象类的匿名内部类
        Animal animal = new Animal(){
            @Override
            void eat() {
                System.out.println("小狗吃骨头");
            }
        };
        animal.eat();
    }
}
class Father{
    public Father(String name) {
        System.out.println("name" + name);
    }
    public void test(){
        System.out.println("test方法");
    }
}
abstract class Animal{
    abstract void eat();
}

  4. 匿名内部类的注意事项

    1) 匿名内部类的语法比较奇特,请大家注意,因为匿名内部类即时一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面的代码分析可以看出这个特点,因此可以调用匿名内部类方法。

    2)可以直接访问外部类的成员,包含私有的

    3)不能添加访问修饰符,因为它的地位就是一个局部变量

    4)作用域:仅仅在定义它的方法或代码块中

    5)匿名内布列-------》访问---------》外部类的成员                访问方式  :直接访问

    6)外部其它类----》不能访问------》匿名内部类 (因为匿名内部类地位是一个局部变量)

    7)如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问

new Person(){
    @Override
    public void hi() {
        System.out.println("匿名内部类重写了 hi 方法,哈哈...");
    }
    @Override
    public void ok(String str) {
        super.ok(str);
    }
}.ok("jack"); //可以直接.方法

  举例:匿名内部类的最佳实践  当作参数直接传递

  

public class InnerDemo01 {
    public static void main(String[] args) {
        f1(new IL() {    //匿名内部类
            @Override
            public void show() {
                System.out.println("这是一幅画");
            }
        });
        
    }
    public static void f1(IL il){  // 静态方法
        il.show();
    }
}
interface IL{   //接口
    void show();
}
//如果用传统方法 还得去写一个类继承 太麻烦

    匿名内部类的经典实现

    

public class InnerDemo02 {
    public static void main(String[] args) {
        Cellphone cellphone = new Cellphone();
        cellphone.alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("小猪起床了");
            }
        });
        cellphone.alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("阿文起床了");
            }
        });
    }
}
interface Bell{
    void ring();
}
class Cellphone{
    public void alarmClock(Bell bell){
        bell.ring();
    }
}

四,成员内部类

  说明:成员内部类时定义在外部类的成员位置,并且没有static修饰

  1. 可以直接访问外部类的所有成员 ,包含私有的

  2. 可以添加任意访问修饰符(public   ,protected , 默认, private) ,因为它的地位就是一个成员

  3. 和外部类的其他成员一样,为整个类体,在外部类的成员方法中创建成员内部类对象,可以调用方法,

  4.成员内部类-----访问 -----》外部类成员(比如属性) 访问方式   : 直接访问

  5,外部类-----》访问---------》成员内部类             创建对象,再访问

  6.外部其它类--------》访问-------》成员内部类

  7.如果外部类和内部类的成员重名时,内部类访问的话。默认遵守就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问

五,静态内部类

  说明:静态内部类时定义在外部类的成员位置,并且有static修饰

  1.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

  2.可以添加任意访问修饰符(public ,protectes, 默认,private) ,因为它的地位就是一个成员

  3. 作用域: 同其他的成员  ,为整个类体

  4. 静态内部类---------》访问---------》外部类 (比如: 静态属性) 访问方式: 直接访问所有静态成员

  5, 外部类 -----访问----》静态内部类     访问方式   :创建对象,再访问

  6, 外部其它类--------》访问---------------》静态内部类

  7,如果外部类和静态内部类的成员重名时,静态内部类访问时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问

 

posted @ 2022-11-27 11:05  阿文程序猿  阅读(60)  评论(0)    收藏  举报