zoukankan      html  css  js  c++  java
  • 内部类(嵌套类)

    嵌套类是指被定义在另一个类的内部的类。

    嵌套类存在的目的是:只是为它的外部类提供服务;

    outer.java里面定义了一个内部类inner,运行时,一旦编译成功,就会生成两个完全不同的.class文件,分别是outer.class和outer$inner.class。

    嵌套类分为四种:静态成员类,非静态成员类(成员内部类),匿名类,局部类。

    内部类:非静态成员类(成员内部类),匿名类,局部类。

    1.静态内部类

     1 public class Outer {
     2 
     3     public static String name = "Joe";
     4     private String password = "0806";
     5 
     6     //静态内部类
     7     public static class inner{
     8         public static void print1(){
     9             System.out.println(name);
    10             //调用外部类的静态方法
    11             outerPrint();
    12         }
    13         public void print2(){
    14             System.out.println(name);
    15         }
    16     }
    17 
    18     public static void outerPrint(){
    19         System.out.println("Outer static method!");
    20     }
    21 
    22     public static void main(String[] args){
    23        //静态内部类的静态方法调用
    24         Outer.inner.print1();
    25         //静态内部类的非静态方法调用
    26         Outer.inner inner = new Outer.inner();
    27         inner.print2();
    28     }
    29 }

    输出结果:

    Joe
    Outer static method!
    Joe

    通过这个例子可以看出:

      ♥ 静态内部类中可以有静态方法,也可以有非静态方法;

      ♥ 静态内部类只能访问其外围类的静态成员和静态方法;

      ♥ 和普通的类一样,要访问静态内部类的静态方法,可以直接“.”出来,不需要一个实例;

      ♥ 要访问静态内部类的非静态方法,必须拿到一个静态内部类的实例对象;

      ♥ 实例化静态内部类:外围类.内部类  xxx = new 外围类.内部类();

    可以把静态内部类看作普通的类,只是碰巧被声明在另一个类的内部而已;如果静态内部类被声明为私有的,那么它就只能在外围类的内部才可以访问。

    非静态成员类(成员内部类)

    成员内部类是最常见的内部类,就是在外部类的基础上按照一般定义类的方式定义类,举个例子:

     1 public class Outer {
     2 
     3     public static String name = "Joe";
     4     private String password = "0806";
     5 
     6     //私有成员内部类
     7     private class PrivateInner{
     8         public void print1(){
     9             System.out.println("private " + name);
    10             System.out.println("public " + password);
    11             //调用外部类的静态方法
    12             outerPrint();
    13         }
    14     }
    15     //公有的成员内部类
    16     public class PublicInner{
    17         public void print2(){
    18             String password = "0810";
    19             System.out.println("public " + name);
    20             System.out.println("public " + password);
    21             //调用外部类的静态方法
    22             outerPrint();
    23         }
    24     }
    25     public static void outerPrint(){
    26         System.out.println("Outer static method!");
    27     }
    28 
    29     public static void main(String[] args){
    30         Outer outer = new Outer();
    31         Outer.outerPrint();
    32         //实例化私有成员内部类
    33         Outer.PrivateInner privateInner = outer.new PrivateInner();
    34         privateInner.print1();
    35         //实例化公有成员内部类
    36         Outer.PublicInner publicInner = outer.new PublicInner();
    37         publicInner.print2();
    38     }
    39 }

    输出结果:

    Outer static method!
    private Joe
    public 0806
    Outer static method!
    public Joe
    public 0810
    Outer static method!

    通过这个例子可以看出:

      ♥ 成员内部类是依附其外围类而存在的,如果要产生一个成员内部类,必须有一个其外围类的实例;

      ♥ 成员内部类不可以定义静态方法和静态属性;

      ♥ 声明为private的成员内部类,只对其外围类可见;声明为public的成员内部类,其他非外围类对其可见;

      ♥ 成员内部类可以访问外围类的私有属性,如果成员内部类的属性和其外围类的属性重名,则以成员内部类的属性值为准;

      ♥ 实例化成员内部类:外围类.内部类 xxx = 外围类.new 内部类();

    匿名内部类

    在多线程的模块中代码,大量使用了匿名内部类,如下:

     1 public class Outer {
     2     //匿名接口
     3     interface Inner{
     4         int getNumber();
     5     }
     6     //使用匿名接口
     7     public Inner getInner(final int num,String str){
     8         return new Inner() {
     9             @Override
    10             public int getNumber() {
    11                 System.out.println(str);
    12                 return num;
    13             }
    14         }; /* 注意:分号不能省 */
    15     }
    16     //测试
    17     public static void main(String[] args){
    18         Outer outer = new Outer();
    19         Inner inner = outer.getInner(4,"nihao");
    20         System.out.println(inner.getNumber());
    21     }
    22 }

    输出结果:

    nihao
    4

     通过这个例子可以看出:

      ❤ 匿名内部类没有修饰符;

      ❤ 当所在方法的形参需要被匿名内部类使用时,该形参必须为final,因为:内部类在编译时会生成一个独立的.class文件,改文件并不在它的外围类中,内部类将传过来的参数通过自己的构造器备份到了自己的内部,这样自己内部方法的调用实际上是自己的属性,而不是外围类方法的参数;简单理解就是:拷贝引用,为了避免引用值发生改变,例如被外围类的方法修改等,而导致内部类得到的值不一致,于是用final修饰让该引用不可变;

      ❤ 匿名内部类没有构造方法,因为它连名字都没有;

      ❤ new 匿名内部类;这个类必须先存在;

    局部内部类

    局部内部类:是指内部类定义在方法和作用域内。

    看个例子:

     1 public class Outer {
     2     private void internalTracking(boolean b) {
     3         if (b) {
     4             //局部内部类
     5             class TrackingSlip {
     6                 private String id;
     7                 TrackingSlip(String s) {
     8                     id = s;
     9                 }
    10                 String getSlip() {
    11                     return id;
    12                 }
    13             }
    14             TrackingSlip ts = new TrackingSlip("slip");
    15             String s = ts.getSlip();
    16         }
    17     }
    18 
    19     public void track() {
    20         //调用方法(含有局部内部类)
    21         internalTracking(true);
    22         System.out.println(".......");
    23     }
    24 
    25     public static void main(String[] args) {
    26         Outer p = new Outer();
    27         p.track();
    28     }
    29 }

    局部内部类也会像其他类一样编译,只是作用域不同而已,只有在该方法或者作用域内才能用,超出作用域或者方法就不可引用。

      ❤ 局部内部类没有访问修饰符;

      ❤ 局部内部类要访问外围类的对象或者变量,那么这个变量或者对象必须是final修饰的;

    内部类的好处

      ❤ Java运行实现多个接口,但不允许继承多个类,使用内部类可以解决Java不允许多个继承的问题。在一个类的内部定义一个内部类,让这个内部类继承某个原有的类,而这个内部类又可以访问外围类的属性和方法,这样就相当于多个继承了;

      ❤ 有效的对外隐藏了自己,增加了自己的私密性;

      ❤ 使用内部类可以让类与类之间的联系更加紧密;

      ❤ 有些类知道只会在某个地方使用只使用一次,为这种类创建一个外部类显然没有必要,所以这种就写个内部类用用就可以了;

    作者:Joe
    努力了的才叫梦想,不努力的就是空想,努力并且坚持下去,毕竟这是我相信的力量
  • 相关阅读:
    集群资源队列监控:Grafana
    1
    3月9号
    jmx
    日常笔记
    nsenter命令简介
    一天2小时
    postgresql Centos7部署
    笔记5
    1
  • 原文地址:https://www.cnblogs.com/Joe-Go/p/9715941.html
Copyright © 2011-2022 走看看