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
    努力了的才叫梦想,不努力的就是空想,努力并且坚持下去,毕竟这是我相信的力量
  • 相关阅读:
    《DSP using MATLAB》Problem 6.17
    一些老物件
    《DSP using MATLAB》Problem 6.16
    《DSP using MATLAB》Problem 6.15
    《DSP using MATLAB》Problem 6.14
    《DSP using MATLAB》Problem 6.13
    《DSP using MATLAB》Problem 6.12
    《DSP using MATLAB》Problem 6.11
    P1414 又是毕业季II
    Trie树
  • 原文地址:https://www.cnblogs.com/Joe-Go/p/9715941.html
Copyright © 2011-2022 走看看