Java中的内部类

成员内部类和方法内部类

将一个类定义在另一个类的里面,里面那个类就称为内部类(内部类也称为嵌套类或者内置类)。内部类分为成员内部类和方法内部类。对于内部类,具有以下的特点:

  • 内部类可以直接访问外部类的成员(包括私有成员)【原理:内部类持有了外部类的引用,该引用是外部类名.this】。
  • 外部类要访问内部类必须先建立内部类的对象。
  • 当内部类是外部类的非私有成员时,可以在其他类中直接建立内部类的对象,格式是:外部类名.内部类名 内部类实例名 = new 外部类名().new 内部类名()
  • 当内部类在外部类的成员位置的时候可以被成员修饰符修饰:

    • 私有private:将内部类进行了封装。
    • 静态static:内部类就具有了静态的特性,只能访问外部类中的静态成员,在外部其他类中可以使用外部类名.内部类名 内部类实例名 = new 外部类名.内部类名() 直接创建内部类的实例(不需要先创建外部类的实例了);如果要访问内部类的静态成员就可以这样:Outter.Inner.静态方法或者变量
    • 当内部类中定义了静态成员,该内部类必须是静态的。
    • 当外部类的方法访问内部类时,内部类必须是静态的。
  • 当内部类处在方法(静态和非静态都一样)中时,不能被成员修饰符修饰(静态或者私有)。
  • 局部内部类访问局部变量,局部变量应该被设置为final类型

访问内部类

class Outer{                              // 定义外部类
    private String info = "hello world" ; // 定义外部类的私有属性
    class Inner{                          // 定义内部类
        public void print(){              // 定义内部类的方法
            System.out.println(info) ;    // 直接访问外部类的私有属性
        }
    }

    // 定义外部类的方法
    public void fun(){                       

        new Inner().print() ;             //通过内部类的实例化对象调用内部类的方法
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        new Outer().fun() ;               // 调用外部类的fun()方法调用内部类的方法
        Outer.Inner inner = new Outer().new Inner();
        inner.print();                    // 直接实例化内部类。格式:外部类.内部类 内部类实例 = new 外部类().new 内部类()    
    }
}

内部类能够访问外部类的原理(内部类持有外部类的引用外部类名.this

class Outer{                             
    private String info = "外部类的info" ; 
    class Inner{                         
        String info = "内部类中的info";
        public void print(){ 
            String info = "内部类的print方法中的info";
            System.out.println(info) ;          // print方法中的info
            System.out.println(this.info);      // Inner中的info,this.info和Inner.this.info等效
            System.out.println(Outer.this.info);// Outer中的info
        }
    }

    // 定义外部类的方法
    public void fun(){                       

        new Inner().print() ;             //通过内部类的实例化对象调用内部类的方法
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        new Outer().fun() ;               // 调用外部类的fun()方法调用内部类的方法
    }
}

静态内部类的一些性质

class Outer{                             
    private static String info = "外部类的info" ; 
    static class Inner{
        /**
         * 静态内部类的非静态方法
         */
        public void print(){ 
            System.out.println(info) ;          // print方法中的info
        }

        /**
         * 静态内部类的静态方法
         */
        public static void fun(){
            System.out.println(info);
        }
    }

    // 定义外部类的方法
    public void fun(){                       

        new Inner().print() ;             //通过内部类的实例化对象调用内部类的方法
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        Outer.Inner inner = new Outer.Inner(); // 访问静态内部类的非静态成员
        inner.print();

        Outer.Inner.fun();                     // 访问静态内部类的静态成员
    }
}

方法内部类

/**
 * 方法内部类
 */
class Outer{                             
    private static String info = "外部类的info" ; 

    public void fun(){

        class Inner{                    // 方法内部类,处于局部,不能被成员修饰符修饰(静态、私有)
            public void print(){
                System.out.println(info);
            }
        }

        new Inner().print();
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        new Outer().fun();
    }
}

方法内部类访问局部变量,局部变量应该是final类型

/**
 * 方法内部类
 */
class Outer{                             
    private static String info = "外部类的info" ; 

    public void fun(final int num){     // 局部变量被final修饰之后才可以被局部内部类访问

        final String msg = "局部中的msg";   // 局部变量被final修饰之后才可以被局部内部类访问
        class Inner{                    
            public void print(){
                System.out.println(msg);
                System.out.println(num);
            }
        }

        new Inner().print();
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        Outer outer = new Outer();
        outer.fun(1); // 局部变量的生存期在栈中,方法运行完之后值就消失
        outer.fun(2);
    }
}

匿名内部类

匿名内部类是内部类的简写格式。匿名内部类必须继承自一个类或者实现某个接口,匿名内部类实际上是匿名子类对象。匿名内部类中的方法一般不会超过3个。

abstract class Abs{
    public abstract void show();
}

/**
 * 匿名内部类
 */
class Outer{                             
    private String info = "外部类的info" ; 

    public void fun(){
        new Abs() {

            @Override
            public void show() {
                System.out.println("show方法执行!" + info);

            }
        }.show();   // Abs的子类对象(因为只有子类才可以覆写抽象方法),调用show方法
    }
}
public class InnerClassDemo{
    public static void main(String args[]){

        Outer outer = new Outer();
        outer.fun();
    }
}

匿名内部类的局限:一次只能调用一次自己的方法。多态的情况下无法向下转型。

abstract class Abs{
    public abstract void show();
}

/**
 * 匿名内部类
 */
class Outer{                             
    private String info = "外部类的info" ; 

    public void fun(){
        new Abs() {

            @Override
            public void show() {
                System.out.println("show方法执行!" + info);

            }
        }.show();   // Abs的子类对象(因为只有子类才可以覆写抽象方法),调用show方法

        new Abs() {

            @Override
            public void show() {
                System.out.println("show方法执行!" + info);

            }

            public void hello(){
                System.out.println("匿名子类自己的hello方法," + info);

            }
        }.hello();  // 匿名内部类一次只能调用自己的一个方法,不能既调用show又调用hello
    }
}

public class InnerClassDemo{
    public static void main(String args[]){

        Outer outer = new Outer();
        outer.fun();
    }
}

因为任何类都是继承自Object类,所以我们可以不实现接口或者显式继承类来创建匿名内部类。

public class InnerClassDemo{
    public static void main(String args[]){

        new Object(){
            void myfun(){
                System.out.println("myfun"); // Object的子类对象
            }
        }.myfun();
    }
}

你可能感兴趣的:(java)