内部类

本文深入解析Java内部类的四种形式:成员内部类、静态内部类、方法内部类(局部内部类)和匿名内部类,包括它们的定义、特点及使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内部类概述:把类定义在其他类的内部,这个类就被称为内部类。

内部类分类:成员内部类、静态内部类、方法内部类(又叫局部内部类)和匿名内部类。

内部类共性:
1.内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
2.内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
3.内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量。

一、成员内部类(member inner class):
格式:外部类名.内部类名 对象名 =外部类对象.内部类对象

class Outer{
    private int num1=52;
    public int num2=1;
    class Inner{
        public void show(){
            System.out.println(num1);
            System.out.println(num2);
        }
    }
}
public class InnerClassOne {
    public static void main(String[] args) {
        Outer.Inner oi=new Outer().new Inner();
        oi.show();  //控制台输出:52 1    
    }
}

二、方法内部类(也叫局部内部类 Local Inner Class)
1.局部内部类定义在方法中,比方法的范围还小,是内部类中最少用到的一种类型。
2.像局部变量一样不能被public, protected, private和static修饰。
3.只能访问方法中定义的final类型的局部变量。
4.局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。(只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化)。

class Outer{
    public int num1=5;
    private int num2=7;
    public void method(){
        int num3=4;//没有修饰符
        final int num4=9;//局部变量用final修饰
        class Inner{
            public void doSomething(){
                System.out.println(num1);//内部类可以自由地访问
                System.out.println(num2);//外部类的成员变量
                System.out.println(num3);
                System.out.println(num4);
            }
        }
        Inner in=new Inner();
        in.doSomething();
        //局部内部类在方法中定义,所以只能在方法中使用,
        //即只能在方法当中生成局部内部类的实例并且调用其方法。
    }

}
public class InnerClassTwo {
    public static void main(String[] args) {
        Outer ou=new Outer();
        ou.method();
    }
}//输出:5 7 4 9

上面说:只能访问方法中定义的final类型的局部变量。这句话感觉等于没说,因为在方法体里面本来就不能使用public, protected, private和static这样的修饰符去修饰局部变量!局部内部类相当于局部变量当然也不能被这些修饰符修饰。这些修饰符是修改类的属性或方法的,不是修饰局部变量的。

三、静态内部类(Static Inner Class)
类定义时加上static关键字
静态内部类中可以定义静态或者非静态的成员
只可以访问外部类的静态成员和静态方法
格式:外部类名.内部类名 对象名 =new 外部类名.内部类名()

class Outer{
    private int num1=3;
    static int num2=5;
    static class Inner{
        //静态内部类中可以定义静态或者非静态的成员
        public void method1(){
            //System.out.println(num1);不能访问外部类非静态成员
            System.out.println(num2);
        }
        public static void method2(){
            //System.out.println(num1);不能访问外部类非静态成员     
            System.out.println(num2);
        }
    } 
}
public class InnerClassThree {
    public static void main(String[] args) {
        //Outer.Inner oi=new Outer().Inner();
        //内部类被静态修饰之后不能通过外部类的对象访问,要用外部类名访问
        Outer.Inner oi=new Outer.Inner();
        oi.method1();
        oi.method2();
    }
}//输出:5 5

四、匿名内部类(Anonymous Inner Class)
其实可以理解为内部类的简化写法
前提:存在一个类(不管是不是抽象的)或者接口
本质:是一个继承了该类或者实现了该接口的子类匿名对象
1.前提为存在一个具体类时

class Demo{
    public void method1(){
        System.out.println("method1");
    }
    public void method2(){
        System.out.println("method2");
    }
}
class Outer{
    public void method(){
        new Demo().method1();
        new Demo().method2();//匿名类直接调方法
    }
}
public class InnerClassFour {
    public static void main(String[] args) {
        Outer ou=new Outer();
        ou.method();
    }
}//输出:method1  method2

2.前提是存在一抽象类或者接口时
要重写接口中的所有方法或抽象类中的所有抽象方法。

interface Demo{
    public void method1();
    public void method2();
}
class Outer{
    public void method(){
        new Demo(){
            public void method1(){
                System.out.println("method1");
                };
            public void method2() { 
                System.out.println("method2");
                };
            }.method1();//虽然只调用一个方法但也要重写接口中所有的方法
    }
}
public class InnerClassFour {
    public static void main(String[] args) {
        Outer ou=new Outer();
        ou.method();
    }
}//输出:method1

虽然只调用一个方法但也要重写接口中所有的方法,当接口中的方法比较多的时候就麻烦了,可以用多态解决。将部分代码改为下面代码就可以输出:method1 method2

class Outer{
    public void method(){
        Demo d=new Demo(){
            public void method1(){
                System.out.println("method1");
                };
            public void method2() { 
                System.out.println("method2");
                };
            };//这部分代码只需写一次
        d.method1();
        d.method2();
    }
}

参考链接:
http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值