JAVA--内部类

1. 一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,最大的特点为可以直接访问私有属性。

2. 类的五大成员:属性、方法、构造器、代码块、内部类。

3. 内部类分类:

3.1 定义在外部类局部位置上:

3.1.1 局部内部类

局部内部类定义在外部类的局部位置,比如方法中,并且有类名

3.1.1.1 可以直接访问外部类的所有成员包括私有成员

3.1.1.2 不能添加访问修饰符,但可以使用final修饰

因为局部内部类相当于一个局部变量,局部变量不能使用修饰符,但可以使用final

局部内部类的实例化在外部类的方法中,作用域仅限于此方法中。

外部类和局部内部类的成员重名时,可通过   外部类名.this.成员  去访问外部类成员,否则内部类成员会覆盖外部类成员。

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

        Outer01 o1 = new Outer01();
        o1.m1();
    }
}

class Outer01{
    private int n1 = 10;
    private void m2() {
        System.out.println("hello?");
    }

    public void m1() {
        final class Inner02 {
            public void f1() {
                System.out.println("n1=" + n1);
                m2();
                //直接访问外部类的私有成员
            }
        }
        Inner02 inner02 = new Inner02();
        //在方法中实例化
        inner02.f1();
    }

}

3.1.2 匿名内部类

3.1.2.1 匿名内部类定义在外部类的局部位置,比如方法中,且没有类名(系统会分配类名,但程序员不可见)

匿名内部类同时是一个对象,当实现接口的类只需要使用一次时,使用匿名内部类可以简化开发

匿名内部类只能使用一次,但实例化的对象可以反复使用

实例:

public class AnonymousInnerClass {
    public static void main(String[] args) {
        A a = new A();
        a.f1();
    }
}

//定义接口
interface IA{
    public void cry();
}

//定义类
class A{
    public void f1() {
        //匿名内部类
        //tiger的编译类型为IA
        //tiger的运行类型为匿名内部类,即A$1
        //在类的方法中把接口实例化
        IA tiger = new IA() {
            @Override
            //重写接口方法
            public void cry() {
                System.out.println("aoaoao");
            }
        };
        tiger.cry();
        System.out.println(tiger.getClass());
        //tiger类型为A$1
    }
}

3.1.2.2 基于类的匿名内部类

class Cat{
    Cat(String name) {
    }
    public void f2() {}
}
class Pet{
    public void f1(){
        //基于类的匿名内部类
        //编译类型为Cat
        //运行类型为匿名内部类
        Cat cat = new Cat("miumiu"){
            //重写类方法
            @override
            public void f2(){
                System.out.println("luelue")
            }
        };
    }
}

当类的一个方法中有多个匿名内部类的时候,系统为其分配的类名递增如Pet$1,Pet$2

3.1.2.3 基于抽象类的匿名内部类

class B{
    public void f1(){
        C c = new C(){
            //抽象类,匿名内部类中必须实现抽象类中的所有抽象方法
            @Override
            void cry(){
                System.out.println("I'm free");
            }
        };
    }
}
//抽象类
abstract class C{
    abstract void cry();
}

3.1.2.4 匿名内部类的使用案例:

传统方法和匿名内部类使用比较:

传统方法通过实现接口的类来定义对象,属于硬编码,一旦实现接口类的内容改变,所有该类实例化的对象都会随之改变。

匿名内部类更加简洁灵活,对于只使用一次的接口实现使用匿名内部类更简单。

public class interface_ {
    public static void main(String[] args) {
        //匿名内部类实现
        //实例化接口作为参数传入函数
        f1(new IA(){
            @Override
            public void show() {
                System.out.println("hhh");
            }
        });
        //传统方法实现
        IAA iaa = new IAA();
        iaa.show();
    }
    //匿名内部类作用函数,接口作为形参
    public static void f1(IA ia) {
        ia.show();
    }
}
interface IA{
    void show();
}
//传统方法的接口实现
class IAA implements IA {
    @Override
    public void show() {
        System.out.println("hello?");
    }
}
//打印结果:
//hhh
//hello?

小结:匿名内部类涉及多态、动态绑定、多态

3.2 定义在外部类的成员位置上(与局部内部类的区别):

3.2.1 成员内部类:

3.2.1.1可直接访问外部类的所有成员,包括私有成员

可以添加任意访问修饰符:static,protected,final

外部类使用内部类,要先创建内部类对象(一般在方法里)再访问

3.2.1.2 外部类其他类使用成员内部类的三种方式 

一:直接声明内部类

public class member_innerclass {
    public static void main(String[] args) {
        Outer01 outer01 = new Outer01();
        Outer01.Inner01 inner = outer01.new Inner01();
        //编译类型为外部类.内部类,使用对象new一个内部类
        inner.f1();
    }
}
class Outer01{
    public class Inner01{
        public void f1(){
            System.out.println("hello?");
        }
    }
}

二:在外部类声明函数,函数中创建调用内部类

public class member_innerclass {
    public static void main(String[] args) {
        Outer01 outer01 = new Outer01();
        outer01.f2();
    }
}
class Outer01{
    //内部类
    public class inner01{
        public void f1(){
            System.out.println("hello?");
        }
    }
    public void f2() {
        //创建inner01对象
        inner01 innerObj = new inner01();
        //调用inner对象方法
        innerObj.f1();
    }
}

Tips:

如果内部类和外部类的成员重名,内部类访问的话会覆盖掉外部类的重名成员,如需访问外部类成员,可通过  外部类.this.成员名  来访问

3.2.2 静态内部类:

使用static修饰

可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

可添加任意访问修饰符(public,protected,private)

外部类访问静态内部类方式:创建对象再访问(和成员内部类相同)

外部其他类访问静态内部类:

        通过类名直接访问

        编写方法(可静态或者非静态)返回静态内部类的对象实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值