【java】内部类

 1、静态内部类

public class Outer {

    int a = 10;
    static int b = 20;

    //静态内部类
    static class Inner {
        public void show1(){
            System.out.println("非静态的方法被调用了");
            Outer o = new Outer();
            System.out.println(o.a);
            System.out.println(b);
        }

        public static void show2(){
            System.out.println("静态的方法被调用了");
            Outer o = new Outer();
            System.out.println(o.a);
            System.out.println(b);
        }
    }
}

外部类Outer定义a为普通变量,b为static修饰的静态变量。

静态内部类Inner中定义普通方法show1和静态方法show2,两种方法a都需要定义外部类o才能访问,b可以直接访问。

public class Test {
    public static void main(String[] args) {
        //创建静态内部类的对象
        //只要是静态的东西,都可以用类名点直接获取
        Outer.Inner oi = new Outer.Inner();
        oi.show1();

        //静态方法
        Outer.Inner.show2();
    }
}

注意事项

1、静态内部类也是成员内部类中的一种
2、静态内部类只能访问外部类中的静态变量和静态方法,
如果想要访问非静态的需要创建外部类的对象。
创建静态内部类对象的格式:

外部类名.内部类名 对象名 = new 外部类名.内部类名();

Outer.Inner oi = new Outer.Inner();

调用非静态方法的格式:

先创建对象,用对象调用

调用静态方法的格式:

外部类名.内部类名.方法名();

2、局部内部类 

将内部类定义到方法里面

public class Outer {
    int b = 20;

    public void show(){
        int a = 10;
        
        //局部内部类
        class Inner{
            String name;
            int age;

            public void method1(){
                System.out.println(a);
                System.out.println(b);
                System.out.println("局部内部类中的method1方法");
            }
            public static void method2(){
                System.out.println("局部内部类中的method2静态方法");
            }
        }

        //创建局部内部类的对象
        Inner i = new Inner();
        System.out.println(i.name);
        System.out.println(i.age);
        i.method1();
        Inner.method2();
    }
}
public class Test {
    public static void main(String[] args) {
        //调用show方法,让代码执行
        Outer o = new Outer();
        o.show();

    }
}


1、将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
2、外界是无法直接使用局部内部类,需要在方法内部创建对象并使用。
3、该类可以直接访问外部类的成员,也可以访问方法内的局部变量。

3、匿名内部类

(1)什么是匿名内部类

隐藏了名字的内部类(不代表没有名字,命名格式为:外部类类名+$+序号)

public class Test {
	public static void main(String[] args) {
		new Swim() {
			@Override
			public void swim() {
				// TODO Auto-generated method stub
				System.out.println("重写Swim()方法");
			}
		};
    }
}

可以写在成员位置,也可以写在局部位置

public class Test2 {
    //是一个没有名字的成员内部类
    Swim s = new Swim(){

        @Override
        public void swim() {
            System.out.println("重写之后游泳方法");
        }
    };
    
    public static void main(String[] args) {
        //回顾一下匿名内部类的格式
        /*
        *
        *           new 类/接口(){
        *               重写的方法;
        *           }
        *
        *
        * */
        
        //是一个没有名字的局部内部类
        //整体我们可以理解为Swim接口的实现类对象
        //接口多态
        Swim s = new Swim(){

            @Override
            public void swim() {
                System.out.println("重写之后游泳方法");
            }
        };

        //编译看左边,运行看右边的原则
        s.swim();

        new Swim(){

            @Override
            public void swim() {
                System.out.println("重写之后游泳方法");
            }
        }.swim();
    }
}

(2)匿名内部类的格式

new 类名或者接口名() {

        重写方法;

}

(3)格式的细节 

包含了继承或实现,方法重写,创建对象

整体就是一个类的子类对象或者接口的实现类对象

(4)使用场景

当方法的参数是接口或者类时

以接口为例,可以传递这个接口的实现类对象

如果实现类只要使用一次(没必要定义一个新的对象),就可以用匿名内部类简化代码

public class Test {
    public static void main(String[] args) {
       /*
            需要大家理解匿名内部类的格式,而不是硬记:
                new 类名或者接口名() {
                 重写方法;
                };
        */


        //编写匿名内部类的代码
        new Swim(){
            @Override
            public void swim() {
                System.out.println("重写了游泳的方法");
            }
        };

        
        new Animal(){
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        };
        
        //在测试类中调用下面的method方法?
        //以前的方式如何调用?
        //要自己写一个子类继承Animal类
        //再创建子类的对象,传递给method方法
        Dog d = new Dog();
        method(d);
        //如果Dog类我只要用一次,那么还需要单独定义一个类太麻烦了。


        method(
                new Animal() {
                    @Override
                    public void eat() {
                        System.out.println("狗吃骨头");
                    }
                }
        );
        

    }
    
    public static void method(Animal a){//Animal a = 子类对象 多态
        a.eat();//编译看左边,运行看右边
    }
}

你可能感兴趣的:(Java,1024程序员节)