内部类包含:实例内部类(成员内部类)、静态内部类、本地内部类、匿名内部类

内部类

概念

内部类就是在一个类中再定义一个类,内部类也是封装的体现,它可以被声明为public、protected、private、默认访问控制符

特点

内部类,可以访问外部类的所有成员变量、方法,包括私有成员。

内部类,可以实现一些特殊的功能,比如:回调函数、事件处理等。

常见的内部类包括:实例内部类(成员内部类)、静态内部类、本地内部类、匿名内部类




1、实例内部类(成员内部类

实例内部类(成员内部类):是指定义在另一个类的实例内部的类

它与静态内部类不同,静态内部类是定义在另一个类中的静态类

实例内部类可以访问外部类的实例变量、方法,也可以定义自己的成员变量、方法

在内部类方法中访问同名的成员时,优先访问自己的;如果要访问外部类同名的成员,语法:外部类名称.this.同名成员名

普通内部类对象,必须在先有外部类对象前提下才能被创建

外部类中不能直接访问内部类中的成员,如果要访问必须先要创建内部类的对象

class Outer {

	// 这个Inner就是内部类
    class Inner {
       ...
    }
}

# 当你想使用实例内部类时,需要首先创建外部类的实例,然后通过外部类的实例来访问内部类

class Demo{
	public static void main(String[] args){
		// 方式1、
		Outer outer = new Outer();
		Outer.Inner inner1 = outer.new Inner();

		// 方式2、
		Outer.Inner inner2 = new Outer.new Inner()
	}
}
实例类内部,不能定义静态成员变量,如果想要定义的话,必须用final修饰,如下
class Outer{
	class Inner{
		public int a;
		public static int b; // 会报错!
		public static final int c = 5; // 正常
	}
}
实例内部类不能定义静态方法,如下
class Outer{
	class Inner{
		public void fun1(){}

		public static void fun2(){} // 会报错!
	}
}
如果实例内部类和外部类的成员变量名相同,那么,实例内部类会先访问自己的成员变量,如下
class Outer{
	public int a = 5;

	class Inner{
		public int a = 10;
	}
}

class Demo {
	public static void main(String[] args){
		Outer outer = new Outer();
		
		Outer.Inner inner = outer.new Inner();

		System.out.println(inner.a); // 10
	}
}



2、静态内部类

静态内部类:指的是,在一个类的内部定义的另一个被static修饰的类。

静态内部类,与普通内部类的区别在于,静态内部类不依赖于外部类的实例,可以直接通过外部类名访问

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

public class OuterClass {
    private static int outerData = 10;

	// StaticInnerClass是一个静态内部类
	// 在其他类中,可以直接通过类名 OuterClass.StaticInnerClass 来创建静态内部类的实例,而不需要先创建外部类的实例
    public static class StaticInnerClass {
        private int innerData;

        public StaticInnerClass(int data) {
            this.innerData = data;
        }

        public void printData() {
            System.out.println("Outer data: " + outerData);
            System.out.println("Inner data: " + innerData);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass(5);
        inner.printData();
    }
}
静态内部类,可以访问外部类的静态成员、静态方法,但是不能访问外部类的非静态成员、非静态方法,如下
class OuterClass{
	// 外部类的成员、方法
	public int a = 5;
	public static int b = 10;

	static class StaticInnerClass{
		public void fun(){
			System.out.println(a); // 报错
			System.out.println(b); // 正常
		}
	}

}
静态内部类中,也可以定义静态成员和静态方法,这些成员和方法与外部类的静态成员和静态方法类似,可以直接通过类名访问,如下
class OuterClass{
	static class StaticInnerClass{
		public static int a = 10;
	}
}

class Demo{
	public static void main(String[] args){
		System.out.println(OuterClass.StaticInnerClass.a); // 10
	}
}
静态内部类的使用场景包括但不限于:

1、将一个类封装在另一个类中,使得外部类的代码更加简洁清晰

2、需要在外部类的静态方法中使用一个类,但又不想将该类声明为外部类的静态成员

3、需要在同一个包中访问一个类,但不想将该类声明为公共类




3、局部内部类

局部内部类,是指,在一个方法,或代码块内部定义的内部类,
与成员内部类不同,局部内部类只能在定义它的方法或代码内部使用,无法在外部访问。

语法格式如下:

class OuterClass{
	// 外部类代码

	void outerMethod(){
		// 外部类方法

		class LocalInnerClass{
			// 局部内部类代码
		}

		// 使用局部内部类
		LocalInnerClass l1 = new LocalInnerClass();
	}
}
特点

1、局部内部类,只能,在定义它的方法或代码块内部使用,无法在外部访问

2、可以访问外部类的成员变量和方法,包括私有成员

3、局部内部类,可以访问方法中的局部变量,但是这些变量必须是final类型的

4、局部内部类,可以实现接口或继承抽象类

5、局部内部类,不能定义静态成员或方法,也不能包含静态代码块

6、不能被public、static等修饰符修饰




4、匿名内部类

匿名内部类,没有类名,直接在创建对象时定义并实现,
通常用于创建只需要使用一次的类对象,可以简化代码,提高代码的可读性。

语法格式如下:

new 类名/接口() {
	// 匿名内部类的类体部分
}
举个例子,
interface MyInterface{
	public void func()
}

# 写法1class Demo {
	public static void main(String[] args){

		// new MyInterface()创建了匿名内部类的实例对象
		new MyInterface(){
			@Override
			public void func(){
				System.out.println("方法的重写");
			}
		}.func() // 这里通过,new出来的匿名内部类对象,进行方法的调用

	}
}
// 会打印出来:方法的重写

# 写法2class Demo {
	public static void main(String[] args){
		// 创建匿名内部类的实例对象
		MyInterface m1 = new MyInterface(){
			@Override
			public void func(){
				System.out.println("方法的重写");
			}
		}
		m1.func()
	}
}
再看一种方式,
class ParentClass {  
    public ParentClass() {  
        // 无参数构造函数  
    }  
      
    public void sayHello() {  
        System.out.println("Hello from ParentClass!");  
    }  
}

public class Main {  
    public static void main(String[] args) {  
        ParentClass parent = new ParentClass() {  
            @Override  
            public void sayHello() {  
                System.out.println("Hello from anonymous class!");  
            }  
        };
        parent.sayHello();  
    }  
}

首先定义了一个父类 ParentClass,其中包含了一个 sayHello 方法,

然后在 Main 类的 main 方法中,我们使用匿名内部类来继承 ParentClass,并在匿名内部类中重写了 sayHello 方法,提供了具体的实现,

这样,我们就可以直接在创建对象的地方定义父类的实现,而不需要专门创建一个新的具名类。

匿名内部类 的 特点

匿名内部类,可以访问,包含它们的类的所有成员(包括私有)
匿名内部类,可以重写父类或实现接口的方法




你可能感兴趣的:(java,java)