Java内部类

简介: 基本概念内部类:是指把一个类的声明放到另一个类的声明中,甚至是放到一个方法内部,这样的类称为 内部类。内部类分为 命名内部类和匿名内部类:命名内部类:就像平时声明一个类一样,有个名字。

基本概念

内部类:是指把一个类的声明放到另一个类的声明中,甚至是放到一个方法内部,这样的类称为 内部类。

内部类分为 命名内部类匿名内部类

  • 命名内部类:就像平时声明一个类一样,有个名字。只是放的位置是另一个类的内部或一个方法的内部。
  • 匿名内部类:就是没有类名,一般将匿名内部类作为参数传递,也就是直接new 出某个类的子类或某个接口的实现类。两种内部类例子下面有
1、在内部类中可以访问它的外部类的所有数据成员和方法成员。通过 “OutterClass.this.” 来访问。
2、内部类中不能定义静态成员,凡是静态的都不可以定义。如果要static ,则同时必须是 final 的。
3、如果在外部类以外创建该内部类的实例,则必须先创建一个外部类的实例,然后再用这个外部类的实例对象创建内部类的实例对象。例子下面有。
4、类中的内部类的访问修饰符只能是public、protected、没有、private之一,好比在类中定义成员变量一样,还可加上abstract、final修饰符
  • 如果内部类的访问修饰符是public的,那么在本包和其他包中的类均可访问。
  • 如果内部类的访问修饰符是protected、或者没有访问修饰符的,那么只本包中的类才可访问。
  • 如果内部类的访问修饰符是private的,那么就只能在外部类中访问。
5、方法中的内部类的访问修饰符只能是 没有,就好比在方法中定义局部变量一样,但可以加上abstract、final修饰符。
  • 这种内部类只有在方法内部可见,其他任何地方均不可见。
  • 这种内部类只有先定义再使用,类中的内部类无此限制,就好比方法中的局部变量必须先定义再使用是一样的。
  • 这种内部类可以访问方法中的变量,但该变量必须是 final 的。

命名内部类 1:

package outterclass1;

/**
 * 下面的代码也许毫无意义,这里只是讨论内部类而已。
 * 
 * 
 */
public class OutterClass {
	private String name = "Outter Class Name";

	// 下面这个InnerClass命名内部类,访问修饰符可以是public、protected、没有、 private
	private class InnerClass {
		private String name = "Inner Class Name";

		/**
		 * 内部类中直接写this是指内部类,而如果先写 外部类名然后写this ,则能访问外部类的属性和方法。
		 */
		public void getOutterClassName() {
			System.out.println(OutterClass.this.name);
		}

		/**
		 * 调用外部类的方法
		 */
		public void invokeOutterClassMethod() {
			f();
		}

		/**
		 * 这里返回的是内部类的 name
		 */
		public String getName() {
			return this.name;
		}
	}

	// 在外部类中声明一个内部类类型的属性
	private InnerClass ic = new InnerClass();

	public void f() {
		System.out.println("这是 OutterClass 的方法");
	}

	public void accessInnerClass() {
		ic.invokeOutterClassMethod();
	}

	public InnerClass getIc() {
		return ic;
	}

	/**
	 * 创建一个外部类对象,并获得内部类对象,然后通过内部类对象拿到外部类的name.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		OutterClass oc = new OutterClass();
		oc.getIc().getOutterClassName();//输出:Outter Class Name
	}
}

命名内部类 2

package outterclass2;

/**
 * 我自己很少使用内部类,暂时还没有发现内部类在实际项目中发挥的作用,尤其是下面的方法中的内部类。
 * 
 * 
 */
public class OutterClass2 {

	// 方法中的内部类的访问修饰符 :没有 、 abstract 、 final
	public void f() {

		String name = "temp variable name";

		class InnerClass {
			private String name = "Inner Class temp variable name";

			public void getOutterName() {
				System.out.println("怎么拿到上面那个name,我还真不知道,欢迎告知....");
			}
		}

		InnerClass ic = new InnerClass();
		ic.getOutterName();
	}

	public static void main(String[] args) {
		OutterClass2 oc2 = new OutterClass2();
		oc2.f(); // 输出:怎么拿到上面那个name,我还真不知道,欢迎告知....
	}
}

匿名内部类

public class OutterClass{
	/**
	 * 这里的参数可以是抽象类,具体类和接口
	 */
	public static void f(Exception e) {
		e.printStackTrace();
	}

	//这里f的参数就是一个 匿名内部类,会立即创建一个该匿名内部类的对象
	public static void testF() {
		f(new Exception() {
			@Override
			public void printStackTrace() {
				System.out.println("NND");
			}
		});
	}

	public static void main(String[] args) {
		testF(); //输出 NND
	}
}

在外部类以外的类中创建内部类的实例:

package outterclass2;

import outterclass1.OutterClass;
import outterclass1.OutterClass.InnerClass;

public class OutterClass3 {
	
	public void f(){
		OutterClass oc = new OutterClass();
		InnerClass ic = oc.new InnerClass();
	}

}

好奇试了哈,还可以在上述内部类中继续定义内部类,内部类的内部类,内部类的内部类的内部类。NND,我只想问这有何意义?

Static Nested Class

  • 在类中定义的内部类,加上static修饰,就成了Static Nested Class
    1. 如果要访问外部类的成员,则该成员必须是 static 的。
    2. 在外部类以外的其他类中创建该 static nested class的对象,外部类的对象可以不创建。如:Outter.Inner inner = new Outter.Inner();
    3. Static Nested Class 中可以定义静态成员,不需要final修饰。与上述讲的内部类不一样
    4. Static Nested Class 的访问修饰符只能是public、protected、没有、private之一,同时也可以有 abstract 、final 修饰符。也就是这个类可以同时被static和abstract修饰,这与abstract method不能同时被static 修饰是不一样的哦。
  • 在静态方法中定义的内部类,也是 Static Nested Class
    1. 这种Static Nested Class的访问修饰符只能是 没有,但可以加上abstract、final修饰符。
    2. 如果要访问外部类的成员,则该成员必须是 static 的。
    3. 如果要访问方法内的成员变量,则必须要被 final 修饰。
    4. 这种Static Nested Class只有在方法内部可见,其他任何地方均不可见。
    5. 也必须先定义,才能使用。
    6. 这种Static Nested Class中不可以定义静态成员,凡是静态的都不可以。如果要static ,则同时必须是 final 的。
  • 如果Static Nested Class的访问修饰符是public的,那么在本包和其他包中的类均访问。
  • 如果Static Nested Class的访问修饰符是protected、或者没有访问修饰符的,那么只能在本包中的类访问。
  • 如果Static Nested Class的访问修饰符是private的,那么就只能在外部类中访问。
好奇也试了哈,还可以在上述Static Nested Class 中继续定义类,类类,类的类的类。NND,我还是只想问这有何意义?

总结:
1、无论是类中的内部类,还是方法中的内部类,还是类中的Static Nested Class,还是静态方法中的Static Nested Class ,他们都可以被 abstract,final修饰。
2、无论是类中的内部类,还是类中的Static Nested Class,他们都可以被public、protected、没有、private之一修饰。
3、无论是方法中的内部类,还是静态方法中的Staitc Nested Class,他们的访问修饰符只能是 没有
4、只有类中的Static Nested Class中才能定义静态成员,同时不需要被final修饰。在其他三个类中如果要定义static成员,则必须加上final修饰。

方法中的成员变量的访问修饰符只能是  没有,只能被 final 修饰。


目录
相关文章
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
Java 编译器
【Java】内部类
【Java】内部类
80 0
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
111 5
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
119 6
|
设计模式 Java 编译器
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
236 2
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
102 0
|
Java 编译器
24. 【Java教程】内部类
24. 【Java教程】内部类
84 2
|
Java 程序员
Java的内部类与匿名类的技术性文章
Java的内部类与匿名类的技术性文章
105 1
|
Java
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
247 3