Java 内部类

Posted 棍子哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 内部类相关的知识,希望对你有一定的参考价值。

一: 内部类
    定义在类体部,方法体部,甚至比方法体更小的代码块内部的类(if 语句里面等)
    1.静态内部类(内部类中最简单的形式)
        1.声明在类体部,方法体外,并且使用static修饰的内部类
        2.访问特点可以类比静态变量和静态方法
        3.脱离外部类的实例独立创建
            在外部类的外部构建内部类的实例
                new Outer.Inner();
            在外部类的内部构建内部类的实例
                new Inner();
        4.静态内部类体部可以直接访问外部类中所有的静态成员,包含私有

          

    
/**
 * @author gress
 *静态内部类
 */
public class StaticInnerTest {
    public static void main(String[] args) {
 
        StaticOuter.StaticInner si = new StaticOuter.StaticInner();
        si.test2();
        //StaticOuter.StaticInner.test();
        System.out.println("si.b = "+si.b);
        System.out.println("si.a = "+si.a);
    //    System.out.println("StaticOuter.b  = "+StaticOuter.b);  这里报错
    }
 
}
 
class StaticOuter {
private int a = 100;
private static int b = 150;
public static void test(){
    System.out.println("Outer static test ...");
}
public  void test2(){
    System.out.println("Outer instabce test ...");
}    
 
static class StaticInner {
        public  int a = 200;
        static int b =300;
        public static void test(){
            System.out.println("Inner static test ...");
        }
        public  void test2(){
            System.out.println("Inner instance test ...");
            StaticOuter.test();
            new StaticOuter().test2();
            System.out.println("StaticOuter.b  = "+StaticOuter.b);
        }    
}
}


    2.成员内部类(实例内部类)
        1.没有使用static修饰的内部类。
        2.在成员内部类中不允许出现静态变量和静态方法的声明。
            static只能用在静态常量的声明上。
        3.成员内部类中可以访问外部类中所有的成员(变量,方法),包含私有成员,如果在内部类中定义有和外部类同名的实例变量,访问:
            OuterClass.this.outerMember;
        4.构建内部类的实例,要求必须外部类的实例先存在
            外部类的外部/外部类的静态方法:new Outer().new Inner();
            外部类的实例方法:
                new Inner();
                this.new Inner();



**
 * @author gress
 * 实例内部类
 *
 */
class MemberOuter{
    
    private String s1 = "Outer InstanceMar";
    private String s2 = "OuterStatic s2";
    public void setS1(String s1) {
        this.s1 = s1;
        new MemberOuter().new MemberInner();
        this.new MemberInner();  //此时MemberOuter已经实例化完成,所以可以使用this
        new MemberInner().test2();
    }
    public static void  test2 (){
        new MemberOuter().new MemberInner();
        /*this.new MemberInner();  
         * 此时MemberOuter没有实例化完成,所以不可以使用this
         * static 是在MemberOuter构造器前使用,所以此时this不能使用
         * 
*/
        
    }
 
 
    class MemberInner{
         String s1= "Inner  instanceMae  ";
        static final String s4 = "static final  MemberInner";
            
                void test2(){
                    System.out.println(" s1 =" + s1);
                    System.out.println(" Outter MemberOuter.this.s1 =" + MemberOuter.this.s1);
                    System.out.println("s2 = "+s2);
                }
    }
    
}
 
public class MemberInnerTest {
 
    public static void main (String args []){
    /*    MemberOuter.MemberInner mm =  new MemberOuter().new MemberInner();
        mm.test2();*/
        
        MemberOuter mo = new MemberOuter();
        mo.setS1("");
        
        
    }
}

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。

如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法
 
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。
在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
3.局部内部类:
        1.定义在方法体,甚至比方法体更小的代码块中
        2.类比局部变量。
        3.局部内部类是所有内部类中最少使用的一种形式。
        4.局部内部类可以访问的外部类的成员根据所在方法体不同。
            如果在静态方法中:
                可以访问外部类中所有静态成员,包含私有
            如果在实例方法中:
                可以访问外部类中所有的成员,包含私有。
          局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。
          
**
 * @author gress 局部内部类
 *
 */
public class LocalInnerTest {
 
    private int a = 1;
    private static int b = 2;
 
    public void test() {
        final int c = 3;
        class LocalInner {
            public void add1() {
                System.out.println("a= " + a);
                System.out.println("b= " + b);
                System.out.println("c= " + c);
            }
        }
        new LocalInner().add1();
    }
 
    static public void test2() {
        final int d = 5;
        class LocalInner2 {
            public void add1() {
                // System.out.println("a= " + a);
                System.out.println("b= " + b);
                System.out.println("c= " + d);
            }
        }
        new LocalInner2().add1();
    }
 
    public static void main(String args[]) {
 
        // LocalInnerTest() lc = new LocalInnerTest();
        new LocalInnerTest().test2();
        new LocalInnerTest().test();
    }
}


    4.匿名内部类
        1.没有名字的局部内部类。
        2.没有class,interface,implements,extends关键字
        3.没有构造器。
        4.一般隐式的继承某一个父类或者实现某一个接口
        5.吃货老师讲的一个很生动的例子
        /**
         * @author gress 匿名内部类,我只会使用一次的类
         * 假如我想吃一个泡面,但我不可能建一个厂,制造一个流水线,生产一包泡面之后就在也不去使用这个泡面厂了
         * 所以这里引申出匿名内部类 ,而我们建立的泡面厂就像这里构建的一个类Pencil 铅笔类一样
         */
    

**
 * @author gress 匿名内部类,我只会使用一次的类
 * 
 * 就假如我想吃一个泡面,但我不可能建一个厂,制造一个流水线,生产一包泡面之后就在也不去使用这个泡面厂了
 * 所以这里引申出匿名内部类 ,而我们建立的泡面厂就像这里构建的一个类Pencil 铅笔类一样
 */
interface Pen {
    public void write();
}
 
class  Pencil implements Pen {
    @Override
    public void write() {
        //铅笔 的工厂
    }
}
 
class Person {
    public void user(Pen pen) {
        pen.write();
    }
}
 
public class AnyInnerTest {
    public static void main(String args[]) {
        Person guo = new Person();
        
        guo.user(new Pen() {
            @Override
            public void write() {
                System.out.println("写子");
            }
        });
    }
 
}



二: abstract  只能单继承
    1.方法:抽象方法
      不能有方法体 
      抽象方法所在类一定是抽象类
      抽象方法存在就是被覆盖的,如果子类继承带有抽象方法的抽象类,必须对所以的抽象方法进行覆盖
      
    2.类 :抽象类
      抽象类不能被实例化
      抽象类是对类的抽象,抽象所具有的共有特征和行为
      抽象类所存在的目的就是用来被继承,实现代码的复用
      抽象类可以有抽象方法也可以没有抽象方法,可以像普通的一个类具有成员变量和方法
      如果一个类继承抽象类,必须实现抽象父类的抽象方法,或者子类也是一个抽象方法

三: interface  可以多实现(继承)
    1.接口是比抽象类还抽象的存在,接口是抽象类的极致抽象。
    2.接口中所有的方法都是public abstracht,接口中所有的变量都是public static final
    3.接口主要用来定义标准。
    4.接口可以多继承。一个类可以实现多个接口。
    5.接口的存在本身可以规避java不能多继承的操作特点。
    interface USBDevice{
    String type="USB";
        void driver();
    }
    
    class Mouse{
        select();
    }
    class USBMouse extends Mouse implements USBDevice{

    }
    
    class Computer{
        void use(USBDevice usb){
            usb.driver();
        }
    }

以上是关于Java 内部类的主要内容,如果未能解决你的问题,请参考以下文章

# Java 常用代码片段

# Java 常用代码片段

elasticsearch代码片段,及工具类SearchEsUtil.java

片段 - 全局视图变量与本地和内部类侦听器和内存泄漏

为啥片段类应该是公开的?

ForegroundService没有从片段开始?