java多种内部类的特点以及区别(附代码)

什么是内部类

内部类是在一个类内部定义的类,内部类中不能定义静态成员,内部类可以访问外部类的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法里面

 

 

内部类有哪几种

一.定义在方法外部的类

1.非静态的内部类(Inner Class)

①访问权限:有四种访问权限,决定了其他类是否能看见这个类.(普通的类只有public和默认两种权限)

②被访问的方式:外部类及其他类访问的时候,需要先创建外部类的实例对象,通过外部类和外部类的实例对象来访问.比如:

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

Outer.Inner1 inner1=outer.new Inner1();//通过外部类创建内部类的实例对象

③访问外部类的成员变量时:可以直接访问外部类的成员变量(无论是静态还是非静态)

2.静态的内部类(静态内部类Static Nest Class)

在一.1的前面加上static,就是静态内部类.不再具有内部类的特性,从狭义上讲,它不是内部类.

Static Nested Class在运行时的行为和功能上,与普通类没有什么区别,只是在引用的时候语法有区别.

①访问权限:有四种访问权限,决定了其他类是否能看见这个类.(普通的类只有public和默认两种权限)

②访问方式:直接使用"外部类名.内部类名"就可以,不用创建外部类的实例对象.比如:

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

③访问外部类的成员变量时:可以直接访问外部类的静态成员变量,访问非静态成员变量的时候需要new Outer().变量名(但是注意这种匿名方式导致每次new出来的都不是一个变量)

二.定义在方法内部的

1.非静态的内部类(Inner Class)

(1)普通的

①访问权限:前面不能加权限修饰符,就好像局部变量一样,但是前面可以加final和abstract.(其他类是不可以直接访问方法内的内部类的,即不可见的,但是内部类创建的实例对象是可以传递给其他类的.)

②访问方式:必须先定义,后使用,即这种内部类的定义代码必须出现在使用该类的代码之前.和局部变量的使用一样.只在在方法内部使用内部类,直接创建内部类对象就行,不需要借助外部类

③访问外部类的成员变量时:可以直接访问外部类的成员变量(无论是静态还是非静态)

④访问包含该内部类的方法中的局部变量时:可以访问,但不能修改

(2)匿名的

在方法的内部还可以定义匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无须为该子类定义名称:

public Class Outer{
	public void start(){
		new Thread(
				new Runable(){
					public void run(){};
				}
				).start();
	}
}

 

2.静态的内部类(静态内部类Static Nest Class)

这个静态内部类被静态方法包含着,并且这个静态内部类前面不能有static(这一点和二.1一样,方法中的内部类前面除了final和abstract不能加别的修饰符)

①访问权限:前面不能加权限修饰符,就好像局部变量一样,但是前面可以加final和abstract.(其他类是不可以直接访问方法内的内部类的,即不可见的,但是内部类创建的实例对象是可以传递给其他类的.)

②访问方式:必须先定义,后使用,即这种内部类的定义代码必须出现在使用该类的代码之前.和局部变量的使用一样.只在在方法内部使用内部类,直接创建内部类对象就行,不需要借助外部类

③访问外部类的成员变量时:可以直接访问外部类的静态成员变量,访问非静态成员变量的时候需要new Outer().变量名(但是注意这种匿名方式导致每次new出来的都不是一个变量)

④访问包含该内部类的方法中的局部变量时:可以访问,但不能修改

 

 

例子

package nest_class_test;

import java.util.ArrayList;
import java.util.List;

public class OuterClass1 {

	int memberVariables=1;
	static int staticMemberVariables=1;
	
	/**
	 * 方法外的内部类
	 * @author WaterFashion
	 *
	 */
	public class InnerClass1{
		public String innerMethod1() {
			memberVariables+=1;
			staticMemberVariables+=1;
			String result="类的成员变量:"+memberVariables+"|类的静态成员变量:"+staticMemberVariables;
			return "访问方法外部的内部类|"+result;
			
		}
	}
	/**
	 * 方法外的静态内部类(只能在方法外,方法内部的内部类不能加static修饰符)
	 * @author WaterFashion
	 *
	 */
	public static class StaticInnerClass1{
		public String innerMethod1() {
			staticMemberVariables+=1;
			//memberVariables+=1;//不可以直接调用静态的成员变量
			String result="类的静态成员变量:"+staticMemberVariables+"|类的非静态成员变量"+new OuterClass1().memberVariables;
			return "访问方法外部的静态内部类|"+result;
		}
	}
	
	
	public String addOuter1() {
		List<String> list=new ArrayList<String>();
		final int localInt=1;
		int finalLocalInt=1;
		/**
		 * 方法内部的内部类
		 * @author WaterFashion
		 *
		 */
		class InnerClass2{
			String innerMethod2() {
				memberVariables+=1;
				staticMemberVariables+=1;//可以引用修改外部类中的成员变量(无论是否是静态)
				list.add("1");//修改里面的值可以,想修改list的指向是不可以的(比如上面声明的时候让list为"null",这里再初始化为"new ArrayList()"是不可以的)
				//localInt+=1; final类型不能修改
				String result="类的成员变量:"+memberVariables+"|类的静态成员变量:"+staticMemberVariables+"|方法的变量"+localInt+"|方法的final局部变量"+finalLocalInt;
				return "访问方法内部的内部类|"+result;
			}
		}
		//调用方法内的内部类
		InnerClass2 innerClass2=new InnerClass2();
		System.out.println(innerClass2.innerMethod2());
		return "addOuter1";
	}
	
	
	public static String staticAdd() {
		int localInt=1;
		final int finalLocalInt=1;
		/**
		 * 静态方法中的内部类也是静态内部类
		 * @author WaterFashion
		 *
		 */
		class InnerClassOfstaticMethod{
			String InnerClassOfstaticMethodAdd() {
				//memberVariables+=1;//不可以直接调用静态的成员变量
				staticMemberVariables+=1;
				//局部变量能引用不能修改
				//localInt+=1;
				//finalLocalInt+=1; 
				String result="|类的静态成员变量:"+staticMemberVariables+"|类的非静态成员变量"+new OuterClass1().memberVariables+"|方法的变量"+localInt+"|方法的final局部变量"+finalLocalInt;
				return "访问静态方法中的内部类|"+result;
			}
		}
		//调用静态方法中的内部类,直接创建对象即可
		InnerClassOfstaticMethod innerClassOfstaticMethod=new InnerClassOfstaticMethod();
		System.out.println(innerClassOfstaticMethod.InnerClassOfstaticMethodAdd());
		return "staticAdd";
	}
	
	/**
	 * 在外部类中调用内部类(在其他类中调用同理)
	 * @param args
	 */
	public static void main(String[] args) {
		//创建外部类的实例对象
		OuterClass1 outerClass1=new OuterClass1();
		//调用方法外的内部类(非静态)(只能通过调用方法来调用方法中的内部类,无论在外部类还是在其他类中)
		OuterClass1.InnerClass1 innerClass1=outerClass1.new InnerClass1();
		System.out.println(innerClass1.innerMethod1());
		//通过外部类的对象调用方法从而调用方法中的内部类
		outerClass1.addOuter1();
		//调用方法外的静态内部类
		OuterClass1.StaticInnerClass1 staticInnerClass1=new OuterClass1.StaticInnerClass1();
		System.out.println(staticInnerClass1.innerMethod1());
		//直接调用静态方法中的内部类(在其他类中调用时,前面必须加外部类的类名)
		staticAdd();
	}
}

 

如有问题敬请指正.

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值