Java内部类与匿名类

内部类

定义:
一个类的内部又完整的嵌套了另一个类结构,被嵌套的类就被我们称为内部类,嵌套内部类的类被我们称为外部类
//外部类
class Outer
{
	//内部类
	class Inner
	{
	
	}
}
package Innerclass;

//外部其他类
public class c1 {
}

class Outer
{
    //属性
    private int n1 = 100;
    //方法
    public void m1()
    {
        System.out.println("m1()");
    }
    //内部类
    class Inner
    {
        
    }
}
内部类的分类
1、定义在外部类局部位置上(比如方法内)
(1)局部内部类(有类名)

(2)匿名内部类(没有类名)

2、定义在外部类的成员位置上
(1)成员内部类(没用static修饰)
(2)静态内部类(使用static修饰)

1、局部内部类

1、局部内部类是定义在外部类的方法中的
2、并且局部内部类可以访问外部类的所有成员包括私有的,访问的方法是直接访问,外部类在方法中可以创建内部类的对象,然后通过内部类的对象去调用其方法
3、不能添加访问修饰符,和局部变量一样,可以用final来修饰
4、作用域只在局部类的方法体内
5、外部其他类不能访问局部内部类(因为局部内部类的地位是一个局部变量)

package Innerclass;

public class LocalInnerClass {
    public static void main(String []args)
    {
        Outer02 outer02 = new Outer02();
        outer02.m1();
    }
}
//外部类
class Outer02
{
    //属性
    private int n1 = 100;
    //私有方法
    private void m2()
    {
        System.out.println("m2");
    }
    //方法
    public void m1()
    {
        //局部内部类通常定义在外部类的方法中
        //局部内部类
        class Inner02
        {
            //局部内部类可以访问外部类的所有成员,包含私有的
            public void f1()
            {
                m2();
                System.out.println("n1 = " + n1);
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }
}

6、如果外部类和内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员)

Out02.this.n2

匿名内部类

1、本质是类
2、内部类, 但实际是有名字的,只不过用完之后会立即被销毁
3、该类是没有名字
4、同时还是一个对象

匿名内部类创建之后,会立马实例化出来,然后这个匿名类内部类就不能再被使用了,但实例化出来的对象是可以反复调用的

基于接口的匿名内部类使用

package Innerclass;

public class AnonymousInnerClass {
    public static void main(String []args)
    {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}
class Outer04
{
    private int n1 = 10;
    public void method()
    {
        //基于接口的匿名内部类
        //tiger的编译类型?IA
        //tiger的运行类型?就是匿名内部类
        /*
            底层是
            class XXXX implements IA
            {
                public void cry()
                {
                    System.out.println("老虎叫唤...");
                }
            }
         */
        IA tiger = new IA()
        {
            public void cry()
            {
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger的运行类型 = " + tiger.getClass());
        tiger.cry();
    }
}

interface IA{
    public void cry();
}

image

基于类的匿名内部类

package Innerclass;

public class AnonymousInnerClass {
    public static void main(String []args)
    {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}
class Outer04
{
    private int n1 = 10;
    public void method()
    {
        //基于接口的匿名内部类
        //tiger的编译类型?IA
        //tiger的运行类型?就是匿名内部类
        /*
            底层是
            class XXXX implements IA
            {
                public void cry()
                {
                    System.out.println("老虎叫唤...");
                }
            }
         */
        IA tiger = new IA()
        {
            public void cry()
            {
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger的运行类型 = " + tiger.getClass());
        tiger.cry();

        //正常new一个对象
        Father father1 = new Father();
        System.out.println("father1对象的运行类型是=" + father1.getClass());

        //匿名内部类
        Father father = new Father()
        {
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        };
        System.out.println("father对象的运行类型=" + father.getClass());
        father.test();
        Animal animal = new Animal()
        {
            @Override
            public void say() {
                System.out.println("小狗吃骨头");
            }
        };
        animal.say();
    }
}

interface IA{
    public void cry();
}

class Father
{
    public void test() {}
}

abstract class Animal
{
    public void say()
    {}
}

image

匿名内部类的使用细节

匿名内部类的定义比较特殊,本身是一个类同时还是一个对象

先定义一个匿名内部类,接收之后,再用生成的对象

image

不接收直接调用

image

package Innerclass;

public class AnonymousInnerClassDetail
{
    public static void main(String[] args)
    {
        Outer05 outer05 = new Outer05();
        outer05.f1();
    }
}

class Outer05
{
    private  int n1 = 99;
    public void f1()
    {
        Person person = new Person()
        {
            @Override
            public void hi() {
                System.out.println("匿名内部类重写了hi");
            }
        };
        person.hi();

        //也可以直接调用
        new Person()
        {
            @Override
            public void hi() {
                System.out.println("匿名内部类重写了hi");
            }
        }.hi();
    }

}
class Person
{
    public void hi()
    {
        System.out.println("Person hi");
    }

}

匿名内部类的实践

匿名内部类主要用于当前类只使用一次,使用过后我们就不会再反复使用,这样我们就没有必要专门再写一个类。

package Innerclass;

public class InnerClassExercise01 {
    public static void main(String[]args)
    {
       f1(new IL() {
           @Override
           public void show() {
               System.out.println("这是一幅名画");
           }
       });
    }
    public static void f1(IL il)
    {
        il.show();
    }
}
interface IL
{
    void show();
}
package Innerclass;

public class InnerClassExercise02 {
    public static void main(String[] args)
    {
        CellPhone cellPhone = new CellPhone();
        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });
        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙伴们上课");
            }
        });
    }
}

interface Bell
{
    void ring();
}

class CellPhone{
    public void alarmclock(Bell bell)
    {
        bell.ring();
    }
}

成员内部类

1、成员内部类是定义在外部类的成员位置,并且没有static修饰。
2、成员内部类可以直接访问外部类的所有成员,包括私有成员。
3、外部类访问内部类,就是直接创建一个内部类然后通过类进行访问。
4、我们可以用public、private、protected去修饰,因为它本身就是一个成员

package Innerclass;

public class MemberInnerClass {
    public static void main(String [] args) {
        Outer08 outer08 = new Outer08();
        outer08.t1();
    }
}

class Outer08{
    private int n1 = 10;
    public String name = "张三";
    class Inner08{
        public void say()
        {
            System.out.println("n1 = " + n1 + " name = " + name);
        }
    }
    public void t1(){
        Inner08 inner08 = new Inner08();
        inner08.say();
    }
}

外部其他类使用成员内部类的两种方式
1、
image
2、
image

静态内部类

比上个内部类多了一个static修饰符
1、静态内部类,在外部类的成员位置,有static修饰
2、可以访问外部类的所有静态成员,非静态不能访问
3、作用域为整个类体

package Innerclass;

public class StaticInnerClass {
    public static void main(String[] args) {
        Outer10 outer10 = new Outer10();
        outer10.m1();
    }
}

//外部类
class Outer10{
    private int n1 = 10;
    private static String name = "张三";
    //静态内部类,在外部类的成员位置,有static修饰

    //可以访问外部类的所有静态成员,非静态不能访问
    //作用域为整个类体
    static class Inner10{
        public void say(){
            System.out.println(name);
        }
    }
    public void m1(){
        Inner10 inner10 = new Inner10();
        inner10.say();;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值