java面向对象进阶进阶篇

2025-12-26 19:55:43

一、成员内部类Java 中的成员内部类是定义在另一个类中的类。它具有与普通类相似的结构,但有一些特殊的访问规则和使用方式。

特性:定义方式:成员内部类的定义方式如下:

代码语言:javascript复制public class OuterClass {

// 外部类的成员和方法

class InnerClass {

// 内部类的成员和方法

}

}内部类 InnerClass 定义在外部类 OuterClass 的内部,可以直接访问外部类的成员变量和方法,包括私有成员。

访问规则:外部类可以直接访问内部类的成员,包括私有成员。内部类可以访问外部类的所有成员,包括私有成员。内部类可以被声明为 private、protected、public 或 package-private(默认),其访问权限不影响外部类对内部类的访问权限。实例化:成员内部类需要通过外部类的实例来实例化,例如:

代码语言:javascript复制OuterClass outer = new OuterClass();

OuterClass.InnerClass inner = outer.new InnerClass();这里 new InnerClass() 必须依附于一个外部类的实例 outer。

生命周期:成员内部类的生命周期和外部类的实例绑定,如果外部类实例被销毁,则内部类实例也无法再被访问。

静态成员:成员内部类可以包含静态成员(静态字段或静态方法),但不能有静态的顶层类(即不能声明为 static class InnerClass)。

使用场景:封装性:可以将内部类隐藏在外部类中,只有外部类才能访问,从而增强了封装性。逻辑关联:当内部类只对外部类可见并且仅用于实现外部类的一部分功能时,使用成员内部类能够更清晰地表达逻辑关联性。回调函数:内部类通常用于实现回调函数,例如事件监听器的实现方式。复杂数据结构:可以使用内部类来实现复杂的数据结构,例如迭代器等。示例:代码语言:javascript复制Outer类 :代码语言:javascript复制package com.von.day15e;

public class Outer {

private int a = 10;

class Inner{

private int a = 20;

public void show(){

int a = 30;

System.out.println(Outer.this.a);//10

System.out.println(this.a);//20

System.out.println(a);//30

}

}

}Text测试类:代码语言:javascript复制package com.von.day15e;

public class Text {

public static void main(String[] args) {

Outer outer = new Outer();//先创建外部类的对象

Outer.Inner inner = outer.new Inner();//再创建内部类的对象

inner.show();

}

}结果展示: 二、静态内部类Java 中的静态内部类是定义在另一个类中且使用 static 修饰的类。静态内部类与非静态内部类(即成员内部类)有着一些重要的区别和特性。

特性:定义方式:静态内部类的定义方式如下:

代码语言:javascript复制public class OuterClass {

// 外部类的成员和方法

static class StaticInnerClass {

// 内部类的成员和方法

}

}内部类 StaticInnerClass 被声明为 static,因此它与外部类 OuterClass 的实例无关,可以直接通过 OuterClass.StaticInnerClass 的方式访问。

访问规则:静态内部类可以直接访问外部类的静态成员和静态方法,包括私有的静态成员。静态内部类不能直接访问外部类的非静态成员和实例方法,因为静态内部类在没有外部类实例的情况下也可以存在。实例化:静态内部类的实例化与普通类类似,不需要依附于外部类的实例,例如:

代码语言:javascript复制OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();生命周期:静态内部类的生命周期与外部类的生命周期无关,它独立存在于外部类之外,直到虚拟机结束或被回收。

静态成员:静态内部类可以包含静态成员(静态字段或静态方法),但不能直接访问外部类的非静态成员。

使用场景:独立功能模块:当内部类不需要访问外部类的实例变量或方法,且希望将其组织为一个独立的类时,可以使用静态内部类。增强封装性:静态内部类可以有效地隐藏实现细节,仅暴露必要的接口给外部。工厂模式:可以将静态内部类作为工厂类,用于创建外部类的实例。辅助类:可以作为外部类的辅助类来实现一些特定的功能,例如迭代器、比较器等。示例:Outer类:代码语言:javascript复制package com.von.day15f;

public class Outer {

//静态内部类

static class Inner{

public void show1(){

System.out.println("静态内部类非静态方法");

}

public static void show2(){

System.out.println("静态内部类静态方法");

}

}

}Text测试类:代码语言:javascript复制package com.von.day15f;

public class Text {

public static void main(String[] args) {

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

inner.show1();//非静态方法

inner.show2();//静态方法

Outer.Inner.show2();//一般用这种方法

}

}结果展示:三、局部内部类局部内部类(Local Inner Class)是定义在方法体内部的类,它与方法的局部变量具有相似的作用域。局部内部类可以访问外部类的成员变量和方法,以及方法中的 final 局部变量(Java 8 之后可以访问非 final 局部变量,但是需要保证该变量在局部内部类中不发生改变)。

特性:定义方式:局部内部类的定义位于方法内部,形式如下:

代码语言:javascript复制public class OuterClass {

// 外部类的成员和方法

public void outerMethod() {

class LocalInnerClass {

// 局部内部类的成员和方法

}

// 在方法内部实例化局部内部类

LocalInnerClass inner = new LocalInnerClass();

}

}访问规则:局部内部类只在方法内部有效,出了方法就无法访问。局部内部类可以访问外部类的所有成员,包括私有成员。局部内部类可以访问方法内的局部变量,但是要求局部变量必须是 final 的或者在 Java 8 及以后版本中被隐式声明为 final。生命周期:局部内部类的生命周期仅限于方法调用过程中,当方法返回时,局部内部类的对象也会被销毁。

使用场景:当一个类仅在方法内部使用,并且对外部代码没有任何意义时,可以考虑使用局部内部类,这样能够将相关逻辑封装在一起,提高代码的局部性和封装性。在需要实现某些接口或继承某个类,并且仅在方法中使用时,局部内部类是一个比较合适的选择。示例:Outer类:代码语言:javascript复制package com.von.day15g;

public class Outer {

int a=10;

public void show(){

int b=20;

//局部内部类

class Inner{

String name;

int age;

public void text1(){

System.out.println("测试一");

}

public void text2(){

System.out.println("测试二");

}

}

Inner inner=new Inner();

inner.text1();

inner.text2();

System.out.println(a);

System.out.println(b);

}

}Text类:代码语言:javascript复制package com.von.day15g;

public class Text {

public static void main(String[] args)

{

Outer outer = new Outer();

outer.show();

}

}结果展示:四、匿名内部类(重点) 匿名内部类(Anonymous Inner Class)是一种没有显式定义类名的内部类,它允许在创建对象的同时定义类的实例。通常情况下,匿名内部类用于创建一个只需使用一次的类的实例,避免了显式定义一个新的类

特性和使用场景:语法:匿名内部类的语法比较特殊,通常在创建对象时使用,形式如下:

代码语言:javascript复制interface Greeting {

void greet();

}

public class Main {

public static void main(String[] args) {

Greeting greeting = new Greeting() {

public void greet() {

System.out.println("Hello, world!");

}

};

greeting.greet(); // 输出 "Hello, world!"

}

}在这个例子中,Greeting 是一个接口,通过匿名内部类的方式实现了 greet() 方法。

特性:匿名内部类没有类名,直接在创建对象的地方定义类的实例。匿名内部类必须继承一个类或实现一个接口,不能同时做到。匿名内部类不能定义任何静态成员、方法和初始化块。匿名内部类可以访问外部类的成员变量和方法,但是外部类的局部变量必须是 final 的或者事实上的 final(Java 8+)。使用场景:事件监听器:在GUI编程中,常常使用匿名内部类作为事件监听器的实现。线程类:在启动线程时,可以通过匿名内部类直接定义线程类的实例。集合类的参数:在某些集合类的方法参数中,需要传递接口实例,可以使用匿名内部类快速实现接口方法。 示例:Animal类:代码语言:javascript复制package com.von.day15g;

public class Animal {

public void eat() {

System.out.println("吃东西");

}

}Swim类:代码语言:javascript复制package com.von.day15g;

public interface Swim {

abstract void swim();

}Text测试类:代码语言:javascript复制package com.von.day15g;

public class Text {

public static void main(String[] args){

new Swim(){

@Override

public void swim() {

System.out.println("匿名内部类实现接口");

}

}.swim();

new Animal(){

@Override

public void eat() {

System.out.println("匿名内部类实现抽象类");

}

}.eat();

methon(

new Animal(){

@Override

public void eat() {

System.out.println("狗吃骨头");

}

});

}

public static void methon(Animal a){

a.eat();

}

}

package com.von.day15g;

public class Text {

public static void main(String[] args){

new Swim(){

@Override

public void swim() {

System.out.println("匿名内部类实现接口");

}

}.swim();

new Animal(){

@Override

public void eat() {

System.out.println("匿名内部类实现抽象类");

}

}.eat();

methon(

new Animal(){

@Override

public void eat() {

System.out.println("狗吃骨头");

}

});

}

public static void methon(Animal a){

a.eat();

}

}Text2测试类:代码语言:javascript复制package com.von.day15g;

public class Text2 {

public static void main(String[] args) {

Swim s = new Swim(){

@Override

public void swim() {

System.out.println("游泳");

}

};

s.swim();

new Swim(){

@Override

public void swim() {

System.out.println("游泳");

}

}.swim();

}

}结果展示:

北京健康宝进化史
盘点四种WiFi加密标准:WEP、WPA、WPA2、WPA3