JavaEE入门级别最全教程7--初学者必看

141 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

内部类

即定义在类内的类。在java中,可以在类的内部再定义一个完整的类。

  • 内部类编译后,可以生成独立的字节码文件 .class
  • 内部类可以直接访问外部类的私有成员,而不是破坏封装。
  • 可为外部类提供必要的内部功能组件。

内部类的分类

内部类,按照定义的位置和修饰符不同,可以分为:

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

成员内部类

概念:在类的内部定义,与实际变量、实际方法同级别的类。

使用

  • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
  • Outer outer = new Outer();
  • Inner inner = outer.new.Innter();

特点

  • 书写位置:与属性、方法平级别,且没有使用static修饰的类
  • 访问权限:内部类可以任意的访问权限
  • 成员内部类中,不能写静态属性、静态方法。
  • 编译之后生成的字节码文件格式:外部类$内部类.class
  • 实例化对象,需要借助外部类的对象完成。

示例代码

// OuterClass.class
package com.laity.basicSyntax.day5.clnnerClass.aMember;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.aMember
 * @date Date : 2021年11月30日 19:27
 * @Description: 成员内部类
 * <p>
 * 访问权限:内部类是作为外部类的一个成员,访问权限可以为是任意权限。
 * 类中的成员定义:成员内部类中,不允许定义静态的成员(静态属性,静态方法)
 */
public class OuterClass {
    public String name;

    // 内部类的定义
    public class InnerClass {
        public String name;

        public void show(String name) {
            System.out.println("参数name=" + name);
            System.out.println("内部类属性name=" + this.name);
            System.out.println("外部类属性name=" + OuterClass.this.name);
        }
    }
}

// Program.class 
package com.laity.basicSyntax.day5.clnnerClass.aMember;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.aMember
 * @date Date : 2021年11月30日 19:27
 * @Description:
 */
public class Program {
    public static void main(String[] args) {
        // 1.外部类对象实例化
        OuterClass outerClass = new OuterClass();
        // 2.访问外部类中的属性
        outerClass.name = "outerClass";
        // 3.实例化一个内部类的对象
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();   // 类型为OuterClass.InnerClass
        // 4.访问内部类的属性
        innerClass.name = "innerClass";
        // 5.调用内部类的方法
        innerClass.show("parameter");
    }
}

// 输出结果
参数name=parameter
内部类属性name=innerClass
外部类属性name=outerClass

静态内部类

**概念:**在类的内部定义,与实例变量、实例方法同级别的,使用static修饰的类。

**使用:**不依赖外部对象,可以直接创建或通过类名访问。

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

特点

  • 书写位置:与属性、方法平级别,且使用关键字 static 修饰的类
  • 访问权限:内部类可以任意的访问权限
  • 静态内部类中,可以写静态属性、静态方法、属性、方法、构造方法。。。
  • 编译之后生成的字节码文件格式:外部类$ 内部类.class
  • 实例化对象,不需要借助外部类的对象完成。

示例代码

// OuterClass.class
package com.laity.basicSyntax.day5.clnnerClass.bStatic;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.bStatic
 * @date Date : 2021年11月30日 19:57
 * @Description: 静态内部类
 */
public class OuterClass {
    public String name;
    public static String name1;

    /**
     * 静态内部类
     */
    public static class InnerClass {
        // 非静态的属性
        public String name;
        // 静态的属性
        public static int age;
        // 方法
        public void show(String name){
            System.out.println("参数name = "+name);
            System.out.println("内部类的属性name = "+this.name);
            System.out.println("外部类的属性name = "+"是访问不到的");
            System.out.println("外部类的静态属性name1 = "+ OuterClass.name1);
        }
    }
}

// Program.class
package com.laity.basicSyntax.day5.clnnerClass.bStatic;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.bStatic
 * @date Date : 2021年11月30日 20:06
 * @Description:
 */
public class Program {
    public static void main(String[] args) {
        // 实例化内部类对象
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();  // 不需要外部类对象

        // 成员访问
        OuterClass.name1 = "outerClass";
        innerClass.name = "innerClass";
        innerClass.show("parameter");
    }
}

// 运行打印结果
参数name = parameter
内部类的属性name = innerClass
外部类的属性name = 是访问不到的
外部类的静态属性name1 = outerClass

局部内部类

**概念:**是定义在外部类的方法中,作用范围和创建对象范围仅限于当前方法。(与成员内部类、静态内部类都不太一样)

特点

  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
  • 不能使用访问权限修饰符修饰。
  • 书写位置:书写在一个类的方法内部,作用域仅限于当前方法。
  • 局部内部类,编译后生成的字节码文件格式:外部类$ 序号 内部类名.class

实例代码

// Program.class
package com.laity.basicSyntax.day5.clnnerClass.cLocal;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.cLocal
 * @date Date : 2021年11月30日 20:48
 * @Description: 局部内部类
 */
public class Program {
    public static void main(String[] args) {
        innerClassTest();
    }

    public static void innerClassTest() {

        // 定义一个变量
        // 如果在一个局部内部类中,使用到了局部变量,那么这个局部变量默认会被定义为 final
        int a = 10;

        /**
         * 局部内部类
         * 访问权限:什么权限都没有,都不可以写
         */
        class InnerClass {
            public String name;
            public int age;

            // 构造方法
            public InnerClass() {
            }

            public void show() {
                System.out.println("局部内部类的show方法");
                System.out.println("a=" + a);
            }
        }
        // a = 20;
        
        // 对象实例化
        InnerClass innerClass = new InnerClass();
        innerClass.show();
    }
}

匿名内部类

**概念:**没有类名的局部内部类

特点

  • 一切特征与局部内部类相同。
  • 必须继承一个父类或者实现一个接口。
  • 定义类、实现类、创建对象的语法合并,只能创建一个改类的对象。

示例代码

package com.laity.basicSyntax.day5.clnnerClass.dAnonymous;

/**
 * @author : Laity
 * @Project: JavaLaity
 * @Package com.laity.basicSyntax.day5.clnnerClass.dAnonymous
 * @date Date : 2021年11月30日 21:07
 * @Description: 匿名内部类
 */
public class Program {
    public static void main(String[] args) {
        // 实例化一个对象
        // 这就是一个匿名内部类
        // 其实,这里实例化的是Person类的一个匿名子类的对象,并实现了向上转型。
        Person laity = new Person() {
            // 匿名内部的类体--->是Person的子类对象
            @Override
            public void walk() {
                // 可以看成Override没有报错
                System.out.println("我是laity");
                super.walk();   // 调用父类的方法
            }
        };

        // 方法调用
        laity.walk();
    }
}

// 定义一个方法
class Person {
    public void walk(){
        System.out.println("Person中的walk");
    }
}