类和对象序章-内部类

一.内部类的概念

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中, 可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类

剧透一下,内部类会在数据结构中用到,比如二叉树类的内部类就是结点类,专门用来服务二叉树

内部类和外部类在同一个.java文件里,但是会生成不同的字节码文件

public class Outer {
class Inner {

}
}

二.实例内部类

定义在类的内部,方法外面的,未被static修饰的内部类称为实例内部类

2.1 实例内部类的实例化

举例如下

public class Outer {
public int data1=10;
private int data2=20;
public static int data3=30;

class Inner {
//定义内部类的成员变量
public int data4=40;
private int data6=60;

//定义内部类的成员方法
public void testInner() {
System. out.println(data1);
}
}
}

要访问实例内部类,就要先实例化一个内部类的对象,语法格式如下

Outer outer=new Outer();//创建外部类对象
Outer.Inner inner=outer.new Inner();//使用外部类对象的引用调用内部类的构造方法

因为内部类也是外部类对象的成员,所以构造内部类对象前要先构造外部类,然后使用外部类对象的引用才能调用内部类的构造方法

内部类的创建还有一个简化版

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

上面的代码先创建了一个外部类对象,然后用这个外部类对象的引用调用了内部类的构造方法

2.2 实例内部类的特性

1.实例内部类可以访问外部类的任何成员

public class Outer {
    public int data1=10;
    private int data2=20;
    public static int data3=30;

    class Inner {
     public int data4=40;
     private int data6=60;
     public void testInner() {
         System.out.println(data1);//访问public成员变量
         System.out.println(data2);//访问private成员变量
         System.out.println(data3);//访问静态成员变量
     }
    }
}
class test {
    public static void main(String[] args) {
        Outer.Inner inner=new Outer().new Inner();//实例化实例内部类
        inner.testInner();
    }
}

下图为运行结果

2.实例内部类里面不能有静态成员变量,除非被final修饰;不可以有静态成员方法

因为实例内部类是依赖外部类对象存在的,而静态成员不需要依赖对象存在,二者发生了冲突,所以语法上不允许这样做。但是静态成员变量经过final修饰后会被编译器看作是常量,可以存在于内部类中。

3.实例内部类和外部类有同名变量时,优先访问自己的变量

public class Outer {
public int data1=10;
private int data2=20;

class Inner {
public int data1=30;
public void test() {
System. out.println("data1="+data1);
}
}
}

执行test方法

class test {
public static void main(String[] args) {
new Outer().new Inner().test();
}
}
//运行结果
data1=30

如果要访问外部类的同名变量,需要使用外部类名.this.变量名

public void test() {
System. out.println("data1="+Outer.this.data1);
}
//输出结果
data1=10

根据这个结果可以推测出实例内部类包含了外部类的引用this

4.实例内部类和外部类的地位相同,其成员也可以被各种限定符修饰

5.外部类不能直接访问内部类的成员(static final修饰的成员变量除外,可以通过类名访问),除非先创建内部类对象

三.静态内部类

被定义在类的内部,方法外面,被static修饰的类

3.1 静态内部类的实例化

静态内部类是外部类的静态成员。所以不依赖外部类的对象

实例化格式如下

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

其中Outer是外部类类名,Inner是内部类类名,Outer.Inner是引用变量inner的指向的对象类型

3.2 静态内部类的特性

1.静态内部类不存在外部类的this引用,不能访问外部类的非静态成员

public class Outer {
    public int data1=10;
    private int data2=20;
    public static int data3=30;

    static class Inner {
        public void test() {
            System.out.println(data1);//报错
            System.out.println(data3);//输出30
        }
    }
}

如何在test方法中访问data1?创建外部类对象

static class Inner {
     public void test() {
        Outer outer=new Outer();
        System.out.println(outer.data1);
     }
}

2.静态内部类不依赖外部类的对象,可通过类名直接访问

public class Outer {
    static class Inner {
        static void test2() {//定义内部类的静态成员方法
            System.out.println("Inner内部的test2()方法");
        }
    }
}

class test {
    public static void main(String[] args) {
     Outer.Inner.test2();//直接通过类名访问test2()方法
    }
}

四.局部内部类

局部内部类是被定义在方法内,只能在该方法中实例化,一般不使用

举例

public static void test() {
        int a=10;
        class Inner {//Inner类被定义在test方法中
            int data1=10;
            double data2=2;
            void test() {
               a=20;//error
                System.out.println(a);
                System.out.println(data1);
            }
        }
        new Inner().test();//在方法内实例化Inner类
    }

1.局部内部类可以访问外部类的成员,但是不能对其更改

2.局部内部类不能被访问限定符,static限制

3.局部内部类只能在方法内部访问

五.匿名内部类

被定义在方法中,在定义的时候通过接口实例化

举例如下

//定义学生类
class Student {
    int age;

    public Student(int age) {
        this.age = age;
    }
}


class test {
    public static void test() {
        Student st1=new Student(10);//创建学生对象1
        Student st2=new Student(12);//创建学生对象2

        int ret=new Comparator<Student>(){//通过接口Comparator创建匿名内部类并实例化
            @Override
            public int compare(Student o1, Student o2) {//匿名内部类内部实现COmparator接口方法compare
                return o1.age-o2.age;
            }
        }.compare(st1,st2);//用刚才创造的对象引用调用compare方法
        System.out.println(ret);//输出compare方法的返回值
    }
    public static void main(String[] args) {
     test();
    }
}
//输出结果
-2

和局部内部类一样,匿名内部类可以访问方法内的变量,但是不能更改变量的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不 会敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值