内部类小结

雨燕双飞 提交于 2019-12-03 05:25:51

1、什么是内部类:就是在一个类的内部声明类。如:

class Outer {
    class inner{
        
    }
}

关于如何访问内部类:

class Outer {
    private int a = 1024;
    
    class Inner {
        public int b = 512;
        
        public void test1(){
            System.out.println(a);//可以访问私有变量
        }
        
    }
    
    public void test2(){
        System.out.println(new Inner().b);
    }
}

public class Demo01 {
    public static void main(String[] args) {
        
        Outer.Inner inner = new Outer().new Inner();
        inner.test1();
    }
}

从上面的例子可以看出内部类的声明方式: 外部类名.内部类名  对象名=new 外部类名().new 内部类名()。

另外:内部类可以访问外部类的成员变量,即使它是外部类所私有的。而外部类想要访问内部类的变量则必须创建该内部类对象才能访问。

2、上面的是一般的外部类,现在介绍私有内部类,即用private修饰的内部类。

public class Demo01 {
    public static void main(String[] args) {
        //私有内部类
        //无法使用Outer.Inner
        //私有内部类方法如何调用?
        //通过在外部内创建私有内部类对象来调用方法
        Outer outer = new Outer();
        outer.test3();
    }
}

class Outer {
    private int a = 1024;
    
    //私有内部类
    private class Inner {
        public int b = 512;
        
        public void test1(){
            System.out.println(a);//可以访问私有变量
        }
        
    }
    
    public void test2(){
        System.out.println(new Inner().b);
    }
    
    public void test3(){
        new Inner().test1();
    }
}

由上可以看出,在外部类的外面是无法访问私有内部类的方法的,只能在外部类中创建内部类的对象,然后访问该方法。

3、静态内部类。用static修饰的内部类。

public class Demo {
    public static void main(String[] args) {
        //创建静态内部类对象 语法:
        Outer.Inner inner = new Outer.Inner();
        inner.test1();
        
        Outer.Inner.test2();//调用静态方法
    }
}

class Outer {
    private static int a = 1024;
    
    static class Inner {
        public int b = 512;
        
        public void test1(){
            System.out.println(a);//可以访问私有变量
        }
        
        public static void test2(){
            System.out.println("test2");
        }
        
    }
    
    
}

可以看出如果想要调用静态内部类的方法,不需要创建内部类的对象,只要:外部类名.内部类名.静态方法();即可。但是静态内部类如果想访问外部内成员变量,该成员变量需要用static修饰。

4、关于类名.this

class Animal {
    public  void test(){
        System.out.println(Animal.this);
    }
}

public class Demo01 {
    public static void main(String[] args) {
        Animal a = new Animal();
        a.test();
        System.out.println(a);
    }
}

结果:


lesson04.Animal@7852e922
lesson04.Animal@7852e922

这说明类名.this其实和this是一样,都是一个该类的对象。如下:

public class Demo01 {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.show();// 10,20,30
    }
}

class Outer {
    public int num = 30;
    class Inner {
        public int num = 20;
        public void show(){
            int num = 10;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}

5、局部内部类。即在方法中定义的内部类。

public class Demo01 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test1();
    }
}

class Outer {
    
    public void test1(){
        //
        int a = 10;//jdk1.8没问题,以下版本要加上final
        
        class Inner {
            public void test2(){
                //Local variable a defined in an enclosing scope must be final or effectively final
                //a = 11; a是被final修饰的
                System.out.println(a);
            }
        }
        
        Inner inner = new Inner();
        inner.test2();
    }
}

如上所示,局部内部类其实和定义在类中的内部类差不多。只是在访问方法中的局部变量时,实际上该变量是final类型的,不可以再次改变其值。在JDK1.8及其以后可以不用显示的声明final。

6、匿名内部类。匿名内部类存在的前提是存在一个抽象类或接口。匿名内部类必须实现所有的抽象方法。匿名内部类实际是抽象类或接口的一个子类对象或实现类对象。

public class Demo01 {
    public static void main(String[] args) {
        //匿名内部类
        //前提是存在一个抽象类或者接口
        //匿名内部类必须是实现抽象类或者接口的所有方法
        //匿名内部类实际是一个匿名对象
        
        //第一种使用方式
        Animal animal = new Animal(){

            @Override
            public void eat() {
                // TODO Auto-generated method stub
                System.out.println("吃东西...");
            }

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("4条腿跑...");
            }
            
        };
        animal.eat();
        //第二种方式
        new Animal(){

            @Override
            public void eat() {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void run() {
                // TODO Auto-generated method stub
                
            }
            
        }.eat();
        
        
        
    }
}

abstract class Animal {
    public abstract void eat();
    public abstract void run();
}

如有错误,请各位大神不吝指出。万分感谢!

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!