Java内部类

本文介绍了Java内部类的四种类型:静态内部类、成员内部类、局部内部类和匿名内部类,通过代码示例展示了它们的用法和访问特性。静态内部类用于不依赖外部类实例的场景,成员内部类可访问外部类的所有成员,局部内部类用于方法内,而匿名内部类常用于简化接口或抽象类的实现。

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

Java内部类


Java内部类是定义在另一个类内部的类。内部类可以访问包含类的成员,包括私有成员,并且可以在外部类的作用域内隐藏其实现细节。

Java内部类可以分为四种类型:

  1. 静态内部类:类似于普通的嵌套类,只是在类定义时使用了static关键字。静态内部类不能访问其外部类实例的非静态成员。
  2. 成员内部类:与静态内部类不同,成员内部类可以访问其外部类实例的所有成员。成员内部类不能定义static成员。
  3. 局部内部类:定义在方法或语句块中的内部类,具有访问方法或语句块的局部变量的能力。
  4. 匿名内部类:没有类名的内部类,通常用来简化代码,实现接口或抽象类的匿名实现。

以下是一个使用成员内部类的示例代码:

public class OuterClass {
    private int x = 10;

    class InnerClass {
        public void printX() {
            System.out.println("x is " + x);
        }
    }
}

在这个例子中,InnerClass是一个成员内部类,它可以访问它的外部类OuterClass的成员变量x。要创建InnerClass的实例,需要先创建OuterClass的实例,然后使用它来创建InnerClass的实例:
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
inner.printX(); // 输出 “x is 10”

静态内部类的案例
下面是一个使用静态内部类的示例,该示例展示了如何在外部类中使用静态内部类来实现从一个整数数组中查找最大值和最小值的功能:

public class ArrayUtils {
    private int[] array;
     public ArrayUtils(int[] array) {
        this.array = array;
    }
     public ArrayStats getArrayStats() {
        return new ArrayStats(this.array);
    }
     public static class ArrayStats {
        private final int[] array;
         public ArrayStats(int[] array) {
            this.array = array;
        }
         public int getMin() {
            int min = Integer.MAX_VALUE;
            for (int i = 0; i < array.length; i++) {
                if (array[i] < min) {
                    min = array[i];
                }
            }
            return min;
        }
         public int getMax() {
            int max = Integer.MIN_VALUE;
            for (int i = 0; i < array.length; i++) {
                if (array[i] > max) {
                    max = array[i];
                }
            }
            return max;
        }
    }
}

在这个例子中,ArrayUtils是一个外部类,它接受一个整数数组作为构造函数参数。它还定义了一个名为ArrayStats的静态内部类,该类可以查找该数组的最小值和最大值。
要使用ArrayStats类,需要首先创建一个ArrayUtils对象,然后调用getArrayStats方法,该方法将返回一个新的ArrayStats对象:
int[] myArray = {1, 2, 3, 4, 5};
ArrayUtils utils = new ArrayUtils(myArray);
ArrayUtils.ArrayStats stats = utils.getArrayStats();
System.out.println("min: " + stats.getMin()); // 输出 “min: 1”
System.out.println("max: " + stats.getMax()); // 输出 “max: 5”
在这个示例中,我们首先创建了一个整数数组myArray,然后使用它创建了一个新的ArrayUtils对象utils。然后,我们调用utils的getArrayStats方法,该方法返回一个新的ArrayStats对象stats,它可以使用getMin和getMax方法来查找myArray的最小值和最大值。

成员内部类的案例

以下是一个使用成员内部类的示例代码,演示了如何在外部类中使用成员内部类来表示一个人的不同属性:

public class Human {
    private String name;
    private int age;
    private Gender gender;
     public Human(String name, int age, Gender gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
     public String getName() {
        return this.name;
    }
     public int getAge() {
        return this.age;
    }
     public Gender getGender() {
        return this.gender;
    }
     public class Gender {
        private boolean isMale;
        private boolean isFemale;
         public Gender(boolean isMale, boolean isFemale) {
            this.isMale = isMale;
            this.isFemale = isFemale;
        }
         public boolean isMale() {
            return this.isMale;
        }
         public boolean isFemale() {
            return this.isFemale;
        }
    }
}

在这个例子中,Human是一个外部类,它具有三个属性:名称,年龄和性别。Gender是一个成员内部类,表示人的性别,它包含两个布尔值:isMale和isFemale。
要创建一个新的人,可以使用Human的构造函数。要访问人的性别,可以使用Human对象的getGender方法,它将返回一个新的Gender对象:
Human person = new Human(“Alice”, 25, new Human.Gender(false, true));
System.out.println("Name: " + person.getName()); // 输出 “Name: Alice”
System.out.println("Age: " + person.getAge()); // 输出 “Age: 25”
System.out.println("Gender: " + person.getGender().isFemale()); // 输出 “Gender: true”
在这个示例中,我们创建了一个新人person,名为Alice,年龄为25,性别为Female。然后,我们使用person的getName和getAge方法分别获取她的名称和年龄。最后,我们使用person的getGender方法获取她的性别,并检查它是否为Female。
局部内部类的案例
下面是一个使用局部内部类的示例代码,演示了如何在方法中使用局部内部类来实现计算器的功能:

public class Calculator {
     public int add(int a, int b) {
        class Adder {
             public int doAdd() {
                return a + b;
            }
        }
        Adder adder = new Adder();
        return adder.doAdd();
    }
}

在这个例子中,Calculator是一个外部类,它包含一个名为add的方法,该方法接受两个整数作为参数并返回它们的和。 在add方法中定义了一个名为Adder的局部内部类,它包含一个名为doAdd的方法,该方法执行实际的加法操作。 add方法将a和b传递给Adder对象,并调用doAdd方法来执行实际的加法操作并返回结果。

要使用这个计算器,可以创建一个新的Calculator对象,然后调用它的add方法:
Calculator calculator = new Calculator();
System.out.println("2 + 3 = " + calculator.add(2, 3)); // 输出 “2 + 3 = 5”
System.out.println("10 + 15 = " + calculator.add(10, 15)); // 输出 “10 + 15 = 25”
在这个示例中,我们创建了一个新的计算器对象calculator,并使用它的add方法来执行加法操作。我们首先传递2和3,然后检查结果是否等于5。然后我们传递10和15,然后检查结果是否等于25。

匿名内部类的案例
以下是一个使用匿名内部类的示例代码,演示了如何在Human类中使用匿名内部类来实现某些操作:

public class Human {
     private String name;
     private int age;
     public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }
     public void sayHello() {
        System.out.println("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
    }
     public void doSomething() {
        Runnable r = new Runnable() {
            public void run() {
                System.out.println("I am " + name + " and I am doing something.");
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}

在这个例子中,Human是一个外部类,它具有两个属性:名称和年龄。 Human还具有两个方法:sayHello和doSomething。在sayHello方法中,Human对象将打印出一个问候消息,其中包含它的名称和年龄。在doSomething方法中,Human对象将创建一个新的Runnable对象,并使用该对象创建一个新的线程。这个Runnable对象是一个匿名内部类,它具有一个run方法,该方法将打印出一个消息,其中包含Human对象的名称和正在执行的操作。
要使用Human对象,并尝试打印一个问候消息,可以执行以下代码:
Human person = new Human(“Alice”, 25);
person.sayHello(); // 输出 “Hello, my name is Alice and I am 25 years old.”
在这个示例中,我们创建了一个新的人person,名为Alice,年龄为25。然后,我们使用person的sayHello方法来打印问候消息。
要使用doSomething方法,可以执行以下代码:
Human person = new Human(“Alice”, 25);
person.doSomething(); // 输出 “I am Alice and I am doing something.”
在这个示例中,我们创建了一个新的人person,名为Alice,年龄为25。然后,我们使用person的doSomething方法来执行某个操作。这将创建一个新的线程,并将Runnable对象传递给它来执行操作。线程将调用匿名内部类中的run方法,打印出一个消息,其中包含人的名称和正在执行的操作。

什么时候用成员内部类、静态内部类、局部内部类、匿名内部类
使用成员内部类:

1.当内部类需要访问外部类的属性和方法时,可以使用成员内部类。
2.当内部类需要在外部类中使用时,可以使用成员内部类。
3.当内部类需要访问外部类的非静态变量时,只能使用成员内部类。

使用静态内部类

1.当内部类不需要访问外部类的非静态变量时,可以使用静态内部类。
2.当外部类的静态变量需要在内部类中使用时,可以使用静态内部类。
3.当内部类需要与外部类的任何实例对象之间没有联系时,可以使用静态内部类。

使用局部内部类:

1.当内部类只需要在某个方法中使用时,可以使用局部内部类。
2.当内部类需要访问某个方法的参数或局部变量时,可以使用局部内部类。
3.当内部类只需要在一个方法中使用时,避免了在整个类中使用不必要的变量、方法等。

使用匿名内部类:

1.当需要创建一个只用一次的类时,可以使用匿名内部类。
2.当需要使用一个已实现的接口或类,但是需要对其进行修改或扩展时,可以使用匿名内部类。
3.当需要在使用时动态创建一个新的类时,可以使用匿名内部类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值