zoukankan      html  css  js  c++  java
  • Java内部类

      Java内部类或嵌套类是在类或接口中声明的类。我们使用内部类在一个地方逻辑地分组类和接口,以便它更可读和可维护。此外,它还可以访问外部类的成员,包括私有数据成员和方法。

    内部类的优点:

    1. 嵌套类代表了一种特殊的类型关系:能访问外部类的所有数据成员和方法(包括私有的)
    2. 嵌套类用于开发更可读和可维护的代码,因为它只在一个地方对类和接口进行逻辑分组。
    3. 代码优化:它需要更少的代码

    问题:

    1. 编辑器为member inner class(成员内部类)生成的内部代码是什么?
    2. 创建annonymous inner class(匿名内部类)的两种方式是什么?
    3. 我们可以在local inner class(局部内部类)中访问非final局部变量吗?
    4. 如何访问static nested class(静态嵌套类)?
    5. 接口中可以定义类吗?
    6. 类中可以定义接口吗?

    nested class(嵌套类)和inner class(内部类)的区别于联系

      内部类是嵌套类的一部分,非静态嵌套类被视为内部类

    嵌套类的类型

      有静态嵌套类和非静态嵌套类两种类型。非静态嵌套类被视为内部类

    • Non-static nested class (inner class) 非静态嵌套类:
      1. member inner class(成员内部类)
      2. annonymous inner class(匿名内部类)
      3. local inner class(局部内部类)
    • static nested class静态嵌套类

    1.成员内部类

      在类内部创建但在方法之外的非静态类称为成员内部类。语法:

     1 class TestMemberOuter1{  
     2  private int data=30;  
     3  class Inner{  
     4   void msg(){System.out.println("data is "+data);}  
     5  }  
     6  public static void main(String args[]){  
     7   TestMemberOuter1 obj=new TestMemberOuter1();  
     8   TestMemberOuter1.Inner in=obj.new Inner();  
     9   in.msg();  
    10  }  
    11 }

      成员内部类的工作原理:

      Java编译器在内部类的情况下创建两个类文件。内部类的类文件名是“outer$inner”。如果要实例化内部类,则必须创建外部类的实例在这种情况下,内部类的实例是在外部类的实例中创建的。

      编译器生成的内部代码:

      java编译器创建一个名为"outer$inner"的类文件。成员内部类具有外部类的引用,这就是为什么成员内部类可以访问外部类的所有数据成员的原因

    import java.io.PrintStream;  
    class Outer$Inner  
    {  
        final Outer this$0;  
        Outer$Inner()  
        {   super();  
            this$0 = Outer.this;  
        }  
        void msg()  
        {  
            System.out.println((new StringBuilder()).append("data is ")  
                        .append(Outer.access$000(Outer.this)).toString());  
        }  
    }

    2.匿名内部类

      一个没有名字的类在Java中被称为匿名内部类。如果您必须重写类或接口的方法,则应该使用它。可以通过两种方式创建Java匿名内部类 

    1. 类(可以是抽象类或具体类)
    2. 接口

      java匿名内部类举例

     1 abstract class Person{  
     2   abstract void eat();  
     3 }  
     4 class TestAnonymousInner{  
     5  public static void main(String args[]){  
     6   Person p=new Person(){  
     7   void eat(){System.out.println("nice fruits");}  
     8   };  
     9   p.eat();  
    10  }  
    11 }  

      匿名内部类的工作原理

    1. 类被创建,但是它的名称由编译器决定,编译器实现Person类,并实现eat方法
    2. 创建匿名类的对象,该对象由Person类型的p引用变量引用。

      编译器生成的代码

    import java.io.PrintStream;  
    static class TestAnonymousInner$1 extends Person  
    {  
       TestAnonymousInner$1(){}  
       void eat()  
        {  
            System.out.println("nice fruits");  
        }  
    } 

    3. 局部内部类

      在方法中创建的类称为Java中的本地内部类。如果要调用本地内部类的方法,必须在该方法中实例化该类。 

      局部内部类举例

     1 public class localInner1{  
     2  private int data=30;//instance variable  
     3  void display(){  
     4   class Local{  
     5    void msg(){System.out.println(data);}  
     6   }  
     7   Local l=new Local();  
     8   l.msg();  
     9  }  
    10  public static void main(String args[]){  
    11   localInner1 obj=new localInner1();  
    12   obj.display();  
    13  }  
    14 }

      编译器生成的内部类:

     1 import java.io.PrintStream;  
     2 class localInner1$Local  
     3 {  
     4     final localInner1 this$0;  
     5     localInner1$Local()  
     6     {     
     7         super();  
     8         this$0 = Simple.this;  
     9     }  
    10     void msg()  
    11     {  
    12         System.out.println(localInner1.access$000(localInner1.this));  
    13     }  
    14 } 

      规则:

    1. 局部内部类不能声明为public、protected、private,只能是默认访问权限
    2. 局部内部类不能被外部方法调用
    3. 局部内部类不能访问非final局部变量在JDK1.7之前,但是可以访问final变量;在JDK1.8以后,局部内部类也可以访问非final局部变量

    4.静态嵌套类

      在类中创建的静态类在Java中称为静态嵌套类。它不能访问非静态数据成员和方法。它可以由外部类名访问。

    1. 它可以访问包括私有的外部类的静态数据成员。
    2. 静态嵌套类不能访问非静态(实例)数据成员或方法

      静态嵌套类举例

    class TestOuter1{  
      static int data=30;  
      static class Inner{  
       void msg(){System.out.println("data is "+data);}  
      }  
      public static void main(String args[]){  
      TestOuter1.Inner obj=new TestOuter1.Inner();  
      obj.msg();  
      }  
    } 

      在这个例子中,你需要创建静态嵌套类的实例,因为他含有实例方法msg()。但是你不需要创建外部类的实例,因为嵌套类是静态的并且静态的属性、方法、类在没有对象情况下可以被访问

      编译器生成的代码:

    1 import java.io.PrintStream;  
    2 static class TestOuter1$Inner  
    3 {  
    4 TestOuter1$Inner(){}  
    5 void msg(){  
    6 System.out.println((new StringBuilder()).append("data is ")  
    7 .append(TestOuter1.data).toString());  
    8 }    
    9 }  

    5. 嵌套接口

      在另一个接口或类中声明的接口称为嵌套接口。嵌套接口用于对相关接口进行分组,以便它们易于维护。嵌套接口必须由外部接口或类引用。它不能直接访问。

      嵌套接口要记住的要点

    1. 嵌套接口在接口内声明时必须是公共的,但是如果在类内声明,则它可以具有任何访问修饰符。
    2. 嵌套接口隐式地声明为静态的

      嵌套接口在接口内声明举例

    interface Showable{  
      void show();  
      interface Message{  
       void msg();  
      }  
    }  
    class TestNestedInterface1 implements Showable.Message{  
     public void msg(){System.out.println("Hello nested interface");}  
      
     public static void main(String args[]){  
      Showable.Message message=new TestNestedInterface1();//upcasting here  
      message.msg();  
     }  
    }
      正如您在上面的示例中看到的,我们通过其外部接口Showable访问Message接口,因为它不能直接访问。就像房间里的衣橱一样,我们不能直接进入衣橱,因为我们必须先进入房间。在集合的框架中, sun microsystem提供了嵌套接口Entry,Entry是Map的子接口,可以通过Map.Entry访问

      java编辑器为嵌套接口生成的代码

    public static interface Showable$Message  
    {  
      public abstract void msg();  
    }

      我们能在接口中定义一个类吗?

      是的,我们可以在接口中定义一个类,java编译器将会创建一个静态嵌套类

    原文地址:https://www.javatpoint.com/java-inner-class

     

     

  • 相关阅读:
    vue列表排序实现中的this问题
    JavaScript:JSON 和 JS 对象
    vue项目设置每个页面的title
    webpack开发和生产两个环境的配置详解
    关于vuex的理解
    vue的路由配置
    js 的静态获取和动态获取
    7 Dockerfile指令详解 && VOLUME 指令
    HAProxy负载均衡保持客户端和服务器Session亲缘性的3种方式
    haproxy开启日志功能
  • 原文地址:https://www.cnblogs.com/boboshenqi/p/9531897.html
Copyright © 2011-2022 走看看