java面向对象.day29(内部类)

发布于:2024-04-28 ⋅ 阅读:(21) ⋅ 点赞:(0)

内部类说明:

  1. 内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。

  2. Java内部类是一种非常强大的特性,它允许你在一个类的内部定义另一个类。内部类可以访问外部类的所有成员,包括私有成员,这提供了一种更紧密的代码组织方式,并且可以在一定程度上增强封装性。

分类:

  1. 实例内部类:实例内部类是最普通的内部类,它没有static修饰符。实例内部类可以访问外部类的所有成员,包括私有成员。要创建实例内部类的对象,必须先创建外部类的对象。

  2. 静态内部类:静态内部类是在外部类中定义为static的类。由于它是静态的,它不能访问外部类的非静态成员(实例变量和实例方法)。静态内部类可以像普通类一样被实例化,并且它的实例化对象可以访问外部类的静态成员。

  3. 局部内部类:局部内部类是在外部类的方法内部定义的类。它的作用域限制在定义它的方法内,并且它可以访问该方法内的局部变量(这些变量必须被声明为final)。局部内部类通常用于解决一些较小范围的问题。

  4. 匿名内部类:匿名内部类是没有名字的内部类,它通常用于实现一个接口或继承一个类,并且只使用一次。匿名内部类常常用于简化代码,特别是在实现接口或重写方法时。

内部类的特点和用途:

  1. 代码组织:内部类可以将一些逻辑上紧密相关的类组织在一起,提高代码的可读性和可维护性。

  2. 数据隐藏:内部类可以访问外部类的私有成员,这种特性可以在一定程度上实现数据隐藏和封装。

  3. 事件监听器:在GUI编程中,内部类常用于实现事件监听器,如按钮点击事件、鼠标移动事件等。

  4. 回调:内部类可以作为回调函数使用,特别是在需要多次调用同一回调函数的情况下。

  5. 单例模式:内部类也常用于实现单例模式,通过将构造方法设置为private,并在外部类中提供一个静态方法来获取内部类的实例。

内部类的创建和使用:

创建内部类对象的一般步骤如下:

  1. 创建外部类对象(对于实例内部类和局部内部类)。

  2. 使用外部类对象(对于实例内部类)或外部类类名(对于静态内部类)来创建内部类对象。

// 创建外部类对象
Outer outer = new Outer();
​
// 创建实例内部类对象
Outer.Inner inner = outer.new Inner();
​
// 创建静态内部类对象
Outer.StaticInner staticInner = new Outer.StaticInner();

对于匿名内部类,你可以直接实例化它,而不需要显式地定义类名:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Running the anonymous inner class");
    }
};
runnable.run();

注意事项:

  • 内部类可以访问外部类的所有成员,包括私有成员。

  • 静态内部类不能访问外部类的非静态成员。

  • 局部内部类可以访问包含它的方法的final局部变量。

  • 内部类持有外部类的隐式引用,这可能会导致内存泄漏,特别是在创建大量的内部类对象时。

内部类是Java语言中一个强大的特性,通过合理使用内部类,你可以编写更加简洁、可维护和可扩展的代码。然而,过度使用内部类可能会使代码结构变得复杂,因此在使用时需要权衡利弊。

代码示例:

实例内部类

public class Outer {
    private String outerVar = "I am in Outer";
​
    // 实例内部类
    public class Inner {
        public void showOuterVar() {
            System.out.println(outerVar); // 可以访问外部类的实例变量
        }
    }
​
    public static void main(String[] args) {
        Outer outer = new Outer(); // 必须先创建外部类的实例
        Outer.Inner inner = outer.new Inner(); // 然后使用外部类实例创建内部类实例
        inner.showOuterVar(); // 输出: I am in Outer
    }
}
​

在这个示例中,Inner 是一个实例内部类。它可以访问外部类 Outer 的所有成员,包括私有成员。要创建 Inner 的实例,必须先创建外部类 Outer 的实例,并使用该实例来创建内部类实例。

静态内部类

public class Outer {
    private static String outerStaticVar = "I am static in Outer";
    private String outerVar = "I am in Outer";
​
    // 静态内部类
    public static class StaticInner {
        public void showStaticVar() {
            System.out.println(outerStaticVar); // 可以访问外部类的静态变量
            // System.out.println(outerVar); // 不能访问外部类的非静态变量
        }
    }
​
    public static void main(String[] args) {
        StaticInner staticInner = new StaticInner();
        staticInner.showStaticVar(); // 输出: I am static in Outer
    }
}
​

在这个示例中,StaticInner 是一个静态内部类。它可以访问外部类 Outer 的静态变量 outerStaticVar,但不能访问非静态变量 outerVar。要创建 StaticInner 的实例,我们不需要外部类 Outer 的实例。

局部内部类

public class Outer {
    public void show() {
        int localVariable = 100;
​
        // 局部内部类
        class LocalInner {
            public void printLocalVariable() {
                System.out.println(localVariable); // 可以访问包含它的方法的局部变量(必须是final的)
            }
        }
​
        LocalInner localInner = new LocalInner();
        localInner.printLocalVariable(); // 输出: 100
    }
​
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.show();
    }
}
​

在这个示例中,LocalInner 是一个局部内部类,定义在 show 方法内部。它可以访问包含它的方法 show 的局部变量 localVariable,但是这个局部变量必须被声明为 final。局部内部类的作用域仅限于包含它的方法内部。

匿名内部类

public class Outer {
    public interface Showable {
        void show();
    }
​
    public void executeShowable(Showable showable) {
        showable.show();
    }
​
    public static void main(String[] args) {
        Outer outer = new Outer();
​
        // 使用匿名内部类实现接口并传递给方法
        outer.executeShowable(new Showable() {
            @Override
            public void show() {
                System.out.println("I am an anonymous inner class implementing Showable");
            }
        });
    }
}
​

在这个示例中,我们创建了一个匿名内部类来实现 Showable 接口,并将其作为参数传递给 executeShowable 方法。匿名内部类在需要一次性使用的情况下非常有用,比如实现一个接口或重写某个方法。