Java中内部类的定义与使用

(一)内部类的基本概念

内部类:所谓内部类就是在一个类的内部进行其他类结构的嵌套的操作。

  • 内部类可以访问外部类的属性,方法;
  • 外部类无法访问内部类的属性,方法,若要访问,需要通过实例化内部类的对象。
  • 内部类使用外部类属性:外部类名.this.属性名—也可只用属性名;
    内部类使用内部类属性:this.属性名——也可只用属性名。
  • 普通类若要访问其他类的属性,需要进行对象引用。

举例如下:

//普通类
//Outer为外部类
class Outer{
	String name = "kelly";

         //Inner为内部类
	class Inner{
	       //内部类中的方法
		public void print(){
		//内部类可以使用外部类的属性,1,直接使用,2,外部类名称.this.属性名
		  System.out.println(Outer.this.name+" is beautiful");
		}
	}
	//外部类中的方法
	public void fun(){
	//外部类不能直接使用内部类的属性和方法,需要对内部类进行实例化
		Inner inner = new Inner();//实例化
		inner.print();//调用内部类的方法
	}
}

//主类
public class TestClass{
	public static void main(String[] args){
		Outer out = new Outer();//对外部类实例化
		out.fun();//调用外部类的方法
	}
}

运行结果如下:

java项目内部调用controller方法 java调用内部类_匿名内部类


引入内部类后,程序的结构有些混乱。虽然内部类破坏了程序的结构,但是从另一方面 来讲,内部类可以方便的操作外部类的私有访问。

可将内部类移出 与 外部类 写成平行类。
普通类若要访问其他类的属性,需要进行对象引用。

修改以上代码:

//Outer类与Inner类都是普通类,并且两个类是平行关系
class Outer{
	String name = "kelly";
	public void fun(){//(3)out对象调用了fun方法
		Inner inner = new Inner(this);//(4)this表示当前对象
		inner.print();//(7)调用Inner类的方法
	}
}
//普通类若要访问其他类的属性,需要进行对象引用
class Inner{
    Outer out; //对Outer类的对象引用
    public Inner(Outer out){//(5)调用Inner的构造方法
		this.out = out;//(6)引用传递
	}	
	public void print(){//(8)执行方法
		 System.out.println(out.name+" is beautiful");
		}
	}
	//主方法
public class TestClass{
	public static void main(String[] args){
		Outer out = new Outer();//(1)实例化Outer类对象
		out.fun();//(2)调用Outer类方法
	}
}

运行结果与上面代码一致:

java项目内部调用controller方法 java调用内部类_匿名内部类_02

(二)内部类为什么存在

内部类为什么存在:

  1. 内部类可以访问外部类的数据;
  2. 其他包中的类看不到内部类,内部类被隐藏,只有其对应的外部类可以看到;
  3. JAVA中只能单继承, 内部类解决单继承缺陷。
    (三)内部类与外部类的关系
  4. 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的;
  5. 内部类是一个相对独立的个体,使用的时候完全独立,但是创建的时候需要引用外部类实例化;
  6. 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素;
  7. 外部类可以通过内部类引用间接访问内部类元素。

内部类创建的两种形式:

  1. 在外部类内部创建内部类

    在外部类内部创建内部类,就像普通对象一样直接创建。
    Inner inner = new Inner();
  2. 在外部类以外的其他类中创建内部类
    外部类.内部类 内部类对象 = new 外部类().new 内部类();
    Outter.Inner inner = new Outter().new Inner();

举例如下:
1,在外部类内部创建内部类

class Outer{
	private String name;
	private int age;
	class Inner{
		public Inner(){
			Outer.this.name = "kity";
			Outer.this.age = 21;
		}
		public void print(){
		  System.out.println(name+" is beautiful,his age is "+age);
		}
	}
	public void fun(){
	//两种方法都可行
		//Outer.Inner inner = new Outer().new Inner();
		Inner inner = new Inner();
		inner.print();
	}
}
public class TestClass{
	public static void main(String[] args){
		Outer out = new Outer();
		out.fun();
	}
}

运行结果如下:

java项目内部调用controller方法 java调用内部类_内部类_03


2,在外部类以外的其他类中创建内部类

class Outer{
	private String name;
	private int age;
	class Inner{
		public Inner(){
			Outer.this.name = "kity";
			Outer.this.age = 21;
		}
		public void print(){
		  System.out.println(name+" is beautiful,his age is "+age);
		}
	}
	public void fun(){
		Inner inner = new Inner();
		inner.print();
	}
}
class Test4{
	public void funnnn(){
	//在其他类中创建内部类的时候注意形式
		Outer.Inner inner = new Outer().new Inner();
		inner.print();
	}
}
public class TestClass{
	public static void main(String[] args){
		Test4 out = new Test4();
		out.funnnn();
	}
}

运行结果与上面代码一致:

java项目内部调用controller方法 java调用内部类_匿名内部类_04

(四)内部类

  • 成员内部类
  • 静态内部类
  • 方法内部类
  • 匿名内部类

1, 成员内部类

  • 成员内部类中不能存在任何static的变量和方法;
  • 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类 。

2, 静态内部类

  • 关键字static可以修饰成员变量、方法、代码块,其实它还可以修饰内部类,使用static修饰的内部类我们称之为静 态内部类。
  • 静态内部类的创建是不需要依赖于外围类,可以直接创建 。
  • 静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类则都可以 。
    举例:
class Outer{
	private static String name = "jack";
	static class Inner{
		public void print(){
		
			//静态内部类使用外部类的实行时,只能调用外部类的static属性
			//此时不能用 (外部类名.this.属性名)形式,直接使用属性名即可
			// System.out.println("姓名为:"+Outer.this.name);---error
			System.out.println("姓名为:"+name);
		}
	}
	public void fun(){
		Inner inner = new Inner();
		inner.print();
	}
}
public class TestClass{
	public static void main(String[] args){
		Outer out = new Outer();
		out.fun();
	}
}

运行结果如下:

java项目内部调用controller方法 java调用内部类_外部类_05

3, 方法内部类(局部内部类)

  • 方法内部类定义在外部类的方法中。
  • 方法内部类和成员内部类基本一致,只是它们的作用域不同,方法内部类只能 在该方法中被使用,出了该方法就会失效。
  • 局部内部类不允许使用访问权限修饰符 public private protected 均不允许。
  • 局部内部类对外完全隐藏,除了创建这个类的方法可以访问它其他的地方是不允许访问的。
  • 局部内部类要想使用方法形参,该形参必须用final声明(JDK8形参变为隐式final声明)。
    举例:
class Outer{
	private String name = "Alice";
	//方法内部类定义在外部类方法中,只能在该方法中使用
	public void display(){
		class Inner{
			public void print(){
				System.out.println(name+" is beautiful!!!");
		}
		}
		new Inner().print();//创建匿名对象并调用方法内部类中的方法
	}
}
public class TestClass{
	public static void main(String[] args){
	Outer out = new Outer();
	out.display();
	}
}

结果如下:

java项目内部调用controller方法 java调用内部类_外部类_06

4, 匿名内部类
匿名内部类其实就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束.除此之外,还有一些地方需要 注意:

  • . 匿名内部类是没有访问修饰符的;
  • 匿名内部类必须继承一个抽象类或者实现一个接口 ;
  • 匿名内部类中不能存在任何静态成员或方法
  • 匿名内部类是没有构造方法的,因为它没有类名
  • 与局部内部相同匿名内部类也可以引用方法形参。此形参也必须声明为 final
  • 匿名内部类最多只能创建一个对象,没办法创建更多对象。