初识Java内部类

初识Java内部类,第1张

初识Java内部类

目录

内部类的定义

内部类的分类

局部内部类

一般格式:

访问方式:

匿名内部类

一般形式:

访问方式:

成员内部类

一般形式:

访问方式:

静态内部类

一般形式:

访问方式:


内部类的定义

把一个类定义在另一个类的内部,内部的类叫做内部类

 //类Inner就是类Outer的内部类,类Outer就是类Inner的外部类
 class Outer {
     class Inner {
     }
 }
内部类的分类

根据定义位置不同将内部类分为2大类

  1. 定义在外部类局部位置(比如方法体或者代码块中)

    • 局部内部类(定义时给出类名)

    • 匿名内部类(定义时不给出类名)

  2. 定义在外部类的成员位置

    • 成员内部类(不使用static修饰)

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

局部内部类

定义在外部类的局部位置,定义时给出类名

作用域:定义内部类的方法或代码块中

  1. 局部内部类可以访问外部类私有属性和方法

  2. 定义在外部类的局部位置,通常在方法中

  3. 不能添加访问修饰符,因为它是一个局部变量类型的

  4. final可以修饰局部变量,所以可以修饰局部内部类

一般格式:
 
class outer {
     
     public void dosome() {
         class Inner {
             
         }
     }
 }
访问方式:
  1. 内部类方法访问外部类属性

    this指的是当前正在访问这段代码的对象,当在内部类中使用this指的就是内部类的对象, 为了访问外层类对象,就可以使用外层类名.this来访问,一般也只在这种情况下使用这种

    外部类.this.属性名

    当内部类属性和外部类属性无重名时可省略外部类.this.,直接使用变量名访问,因为直接使用变量名是采用就近原则

     class Outer {
         //外部类属性age
           private int age = 20;
           public void m1() {
               class Inner {
                   //内部类属性age
                   int age = 40;
                   public void show() {
                       System.out.println(age);//age = 40
                       System.out.println(Outer.this.age);//age = 20
                   }
               }
               Inner i = new Inner();
               //存在重名变量
               i.show();//40   20
               //注释掉内部类里面的age
               i.show();//20   20
          
           }
       }
     public static void main(String[] args) {
             Outer outer = new Outer();
             outer.m1();
     }

  2. 外部类访问内部类

    在作用域中可以创建对象访问

  3. 外部其他类访问内部类

    无法访问,类似于局部变量,不在作用域中

匿名内部类

我们在开发的时候,会看到抽象类,或者接口作为参数。

而这个时候,实际需要的是一个子类对象。

如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。

  1. 本质是继承该类或者实现接口的子类的匿名(其实系统分配了类名可以用getclass查看)对象

  2. 不能添加访问修饰符,因为它是一个局部变量

  3. 作用域:方法或者代码块等

  4. 外部不能访问

  5. 成员重名就近原则,想访问外部类的话外部类.this.成员(如果在主方法中需要创建对象,直接用对象.成员 就可以访问)

一般形式:
 A a = new A(){
     
 }
 ​
 ​
 //底层是继承该类或者实现接口的子类的匿名对象
 ​
 //继承类
 class A extends A{
     
 } 
 //实现接口
 class A implements A{
     
 }
 ​
 A a = new A();
访问方式:

访问方式同局部内部类,区别是局部内部类是一个类,匿名内部类本质是一个实例化的对象

 public class AnonymousIner {
     int num = 90;
     public void f1() {
 ​
         B b = new B(){
             int num = 100;
             @Override
             public void run() {
                 System.out.println("匿名内部类重写父类方法");
                 //访问外部类重名属性90
                 System.out.println(AnonymousIner.this.num);
                 //就近原则100
                 System.out.println(num);
             }
         };
         //返回引用b的运行类型class AnonymousIner
         System.out.println(b.getClass());
         //class AnonymousIner
         System.out.println(new B(){}.getClass());
         b.run();
         System.out.println(b.num);//100
 ​
     }
 ​
     public static void main(String[] args) {
         AnonymousIner aonymousIner = new AnonymousIner();
         aonymousIner.f1();
 ​
     }
 }
 ​
 class B {
     int a = 100;
     public void run() {
         System.out.println("B的方法执行");
     }
 }
 ​
 //运行结果
 class AnonymousIner
 class AnonymousIner
 匿名内部类重写父类方法
 90
 100
 100

成员内部类

定义在外部类的成员位置

  1. 直接访问外部类成员

  2. 可以添加任意访问修饰符

  3. 作用域:整个类体

一般形式:
 class Outer{
   
     class MemberInnerClass{
         int a = 100;
     }
     
 }
访问方式:
  • 外部类访问成员内部类先创建对象,通过对象访问

     
     public void f(){
             System.out.println(new MemberInnerClass().a);//100
     }

  • 外部其他类访问

    成员内部类是以成员变量的形式存在,在外部其他类想访问这个外部类里面的内部类,首先要创建一个外部类对象,new 外部类(),通过这个对象 *** 作外部类里面的内部类,而想 *** 作内部类里面内容还要创建一个内部类对象new 内部类(),通过 new 外部类(). new 内部类().成员 来 *** 作

     
     public void f(){
           
             System.out.println(new Outer().new MemberInnerClass().a);//100
     }
    • 在外部类中编写一个方法返回内部类对象

      public  MemberInnerClass rerurnb(){
             return new MemberInnerClass().new B();
      }

静态内部类

使用static修饰的成员内部类

  1. 放在外部类成员位置

  2. static修饰

  3. 可以直接访问外部类静态成员,不能直接访问成员变量

  4. 可以添加任意访问修饰符

  5. 作用域:整个类体

一般形式:
 class Outer{
   
     static class StaticInnerClass{
         int b = 100;
         static int a = 10;
     }
     
 }
访问方式:
  1. 内部类与外部类相互访问所有静态成员用类名直接访问,非静态成员需创建对象

     StaticInnerClass.a;//静态成员
     new StaticInnerClass().b;//非静态成员

  2. 外部其它类访问静态内部类

    外部类.内部类创建对象

     Outer.StaticInnerClass.b;//静态成员
     new Outer.StaticInnerClass().b//非静态成员

  3. 重名问题就近原则,访问外部类属性使用外部类.成员

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5684884.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存