Java内部类总结

时间:2021-12-04 19:53:07

Java内部类总结

 

本文对java内部类的的定义和使用方法以及它们的应用方向都会做比较全面的介绍。

 

一.相关定义和使用方法

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

 一般来说,有4中内部类:常规内部类、静态内部类、局部内部类、匿名内部类。


其中静态内部类和匿名内部类是我们有时候会使用到的,要会使用就可以了,另外两个内部类,基本不用到。

 

这里先说一下个人理解:内部类在外部类的里面,其实就相当于外部类的成员实例。

和类里面的方法和变量差不多,但是也会有点不同。

基本规则还是要遵守的,比如被static修饰的静态方法不能访问,非静态的方法或变量;

所以main方法不能直接访问没有被静态修饰的内部类方法或变量。

 


(一)成员内部类


使用格式:

public class 外部类 {
   //内部类可以拥有private访问权限、protected访问权限、public访问权限及默
认的访问权限,外部类只能被public和默认访问两种权限修饰
   访问修饰符 class 内部类 {
        //如果成员内部类用private修饰,则只能在外部类的内部访问;
       //如果用public修饰,则任何地方都能访问;
      //如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问 
  //如果是默认访问权限,则只能在同一个包下访问
 }
 }

 

 成员内部类是依附外部类而存在的,也就是说,

如果要创建成员内部类的对象,前提是必须存在一个外部类的对象

 

外部类 a = new 外部类();
外部类.内部类 b = a.new 内部类();  

如果需要访问外部类的属性和方法,需要使用外部类.this实现,如下:
1. 外部类.this.成员变量
2. 外部类.this.成员方法


成员内部类的使用示例:

 

 package com.xykj.inner;

/*
 * 成员内部类的使用
 * 这个类用起来相当复杂,而且用处不大
 * 所以说这个东西,用处很少
 * */
public class InnerTest4 {

	int t1 = 22;// 普通成员变量

	static int t2 = 33;// 静态成员变量

	// 主方法,是静态的哦
	public static void main(String[] args) {

		System.out.println("main");

		// 静态方法不能掉用非静态方法或变量,本类的也不行
		// speak();//报错
		// System.out.println(t1);//报错

		// 正确的调用方法
		InnerTest4 i4 = new InnerTest4();
		i4.speak();
		System.out.println(i4.t1);

		// 静态方法访问静态变量不会报错
		System.out.println(t2);

		/**** 对内部类的访问呢? *****/

		// 访问内部类的非静态方法和变量,这个麻烦
		Inner3 inner3 = i4.new Inner3();//一定要外部类的对象来new内部类
		System.out.println(inner3.i1);
		inner3.read();

		// 访问内部类的静态方法和变量
		System.out.println(Inner3.i2);
	}
	
	//类的静态方法
	public static void drunk(){}
	
	
	// 类的普通方法
	public void speak() {
		
		System.out.println("speak");
		
		// 非静态方法能直接调用静态和非静态的方法或变量 
				speak();
				drunk();
				System.out.println(t1);
				System.out.println(t2);


		/**** 对内部类的访问呢? *****/
				//非静态方法内调用是一样的
				// 访问内部类的非静态方法和变量
				Inner3 inner3 = new Inner3();
				System.out.println(inner3.i1);
				inner3.read();
				
				// 访问内部类的变量
				System.out.println(Inner3.i2);
	}

	/*
	 * 创建一个成员内部类
	 */
	 class Inner3 {

		int i1 = 22;// 普通成员变量

		static final int i2 = 33;// 静态成员变量,一定要加final,否则会报错

		// 普通方法
		public void read() {
			System.out.println("read");
			//访问外部类的方法和变量
			InnerTest4 i4 = new InnerTest4();
			i4.speak();
			System.out.println(i4.t1);
			InnerTest4.drunk();
			System.out.println(InnerTest4.t2);
			
		}

		// 不能有非静态类静态方法
		//public static void write() {}//报错
	}
}




(二)局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,

它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。 

所以它基本上不会用到!


使用格式:


class 外部类{ 
  public void print(){
class 局部内部类{
void print(){
System.out.print("局部内部类");
  }
  }
  局部内部类 a= new 局部内部类();
a.print();
   }
 } 

 

局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

 

局部内部类使用的示例:


package com.xykj.inner;

public class InnerTest5 {
	/**
	 * 局部内部类的使用
	 * 这是一个最没有用的内部类
	 * 在一个方法里面写一个类,在方法外面这个类就没有了
	 * */
	public static void main(String[] args) {
		
		class Inner5{
			 int i=3;
			 void say(){
				 System.out.println(i+"在局部类打印一句话!");
			 }
		 }
		
		//创建一个内部类示例对象
		Inner5 in5= new Inner5();
		//调用内部类的方法
		in5.say();
	}
}



 

(三)匿名内部类 

 

匿名内部类一般是在某个方法里面被调用

匿名内部类是我们使用的最多的方式,

一般来说,都是在实现一个抽象类的或者接口的同时,将他的抽象方法实现,

这时我们的类实际上是该抽象类或者接口的子类,只是没有命名,方法的实际实现每次都不一样,不能去公用,

那么一般直接使用匿名内部类实现。


使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,

但是前提是这个父类或者接口必须先存在才能这样使用


比如下面的例子,线程的启动,也是我们经常会使用的 

 

 

package com.xykj.inner;
import java.io.File;
import java.io.IOException;

public class InnerTest2 {
	/*
	 * 匿名内部类的使用
	 * 使用非常方便,不用新建类就可以调用类里面的方法
	 * */
	public static void main(String[] args) throws IOException {
		 //启动线程
		new Thread(){
			public void run() {
				//在这里添加任务,如下载东西或睡眠
				System.out.println("启动线程,在执行任务!");
			};
			
		}.start();
		
		//这里随便提一下匿名对象的使用,也是我们经常会用到的,比如
		new File("D:/java/jsp").mkdirs();//文件夹的创建
		new File("D:/java/jsp/aa.txt").createNewFile();//文件的创建,
		FileOutputStream fos=new FileOutputStream(new File("D:/java.txt"));//实例化输出流对象
	}

}


 

 

(四)静态内部类 (嵌套类)


静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。

静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,

并且它不能使用外部类的非static成员变量或者方法


静态内部类与普通内部类区别(不记)
1. 嵌套类的对象,并不需要其外部类的对象。 即它可以不依赖于外部类实例被实例化。
2. 不能从嵌套类的对象中访问非静态的外围类对象。这是由Java语法中"静态方法不能直接访问非静态成员"所限定
3. 外部类访问内部类的的成员有些特别, 不能直接访问, 但可以通过内部类实例来访问。
4. 静态内部类可以有静态成员,而非静态内部类则不能有静态成员。
5. 非静态内部类的非静态成员可以访问外部类的非静态变量。 

 

调用静态内部类,和调用另外一个java文件写的普通类是一样的!

 

 示例:


package com.xykj.inner;

/*
 * 静态内部类的使用
 * 静态的内部类和创建的类本身没有什么关系,相当于在外面建了一个类,调用方法和普通类的调用是一样的
 * 所以说这个东西,用处很少
 * */
public class InnerTest3 {

	int t1 = 22;// 普通成员变量

	static int t2 = 33;// 静态成员变量

	// 主方法,是静态的哦
	public static void main(String[] args) {

		System.out.println("main");

		// 静态方法不能掉用非静态方法或变量,本类的也不行
		// speak();//报错
		// System.out.println(t1);//报错

		// 正确的调用方法
		InnerTest3 i3 = new InnerTest3();
		i3.speak();
		System.out.println(i3.t1);

		// 静态方法访问静态变量不会报错
		System.out.println(t2);

		/**** 对内部类的访问呢? *****/

		// 访问内部类的非静态方法和变量
		Inner3 inner3 = new Inner3();
		System.out.println(inner3.i1);
		inner3.read();

		// 访问内部类的静态方法和变量
		System.out.println(Inner3.i2);
		Inner3.write();
	}
	
	//类的静态方法
	public static void drunk(){}
	
	
	// 类的普通方法
	public void speak() {
		
		System.out.println("speak");
		
		// 非静态方法能直接调用静态和非静态的方法或变量 
				speak();
				drunk();
				System.out.println(t1);
				System.out.println(t2);


		/**** 对内部类的访问呢? *****/
				//非静态方法内调用是一样的
				// 访问内部类的非静态方法和变量
				Inner3 inner3 = new Inner3();
				System.out.println(inner3.i1);
				inner3.read();
				
				// 访问内部类的静态方法和变量
				System.out.println(Inner3.i2);
				Inner3.write();
	}

	/*
	 * 创建一个静态内部类
	 */
	static class Inner3 {

		int i1 = 22;// 普通成员变量

		static int i2 = 33;// 静态成员变量

		// 普通方法
		public void read() {
			System.out.println("read");
			
		}

		// 静态方法
		public static void write() {
			System.out.println("write");
			//调用外部类的成员,和调用普通的类是一样的!!
			InnerTest3 it3=new InnerTest3();
			System.out.println(it3.t1);
			InnerTest3.drunk();
		}
	}
}


 

 

以上java内部类的大致内容,但是我们在开发的使用还是尽量少用。

上面除了匿名内部类可以记一下用法,其他的不要记住都可以的。

对内部类的学习,只是为了看得懂内部类的格式,了解不同的代码编程习惯。