java内部类

java内部类的定义及使用

一、内部类的概述

内部类(inner class): 定义在一个类中的另一个类,外层的类称外部类。

为什么要使用内部类?

  1. 内部类可以对同一个包中的其它类隐藏。
  2. 内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
  3. 内部类可以解决java单继承的缺陷

二、内部类的几种类型

1.成员内部类

成员内部类: 即定义在外部类中,与外部类的成员属性以及成员方法同级别的类。

定义格式:

public class Outer{
	private String name="外部类属性";
	private int id = 1;
	private String  str ="outer";
	
	class Inside{
		private String name ="内部类属性";
		private int id = 2;
		public void fun() {
			//打印外部类同名属性
			System.out.println(Outer.this.name);	//外部类属性
			System.out.println(Outer.this.id);		//1
			
			//打印内部类同名属性
			System.out.println(this.name);			//内部类属性
			System.out.println(this.id);			//2
			//直接调用外部类属性
			System.out.println(str);	//outer
			
			outerFun(); 	//内部类中直接调用外部类方法
		}

	}
		public void outerFun() {
		System.out.println("外部类方法");		
	}
	}

创建对象的格式:

class Test{
	public static void main(String[] args) {
		//创建外部对象
		Outer outer = new Outer();
		//创建内部类对象
		Inside inside = outer.new Inside();
		inside.fun();
		
//		直接创建
		Outer.Inside i = new Outer().new Inside();
		i.fun();

两种创建方式:

  1. 先创建外部类对象,再创建内部类对象
  2. 直接创建通过“外部类名称.内部类名称 变量名 = new 外部类名称().new 内部类名称”。

注意事项:
1.当内部类和外部类有【同名变量时】,内部类使用"外部类名称.this.属性名"的方式进行访问外部类属性,内部类则通过this关键字调用自身属性。而当外部类需要访问内部类成员属性时,则需要创建对象;
2. 成员内部类不能定义静态成员这是因为:
内部类要使用需要实例化,在那之前是需要外部类实例化后再去实例化内部类,所以要加载内部类必须在实例化外部类之后完成 ,但是java虚拟机要求所有的静态变量必须在对象创建之前完成, 这样便产生了矛盾。

2.局部内部类

局部内部类: 定义在外部类方法中的类,作用范围和创建对象范围仅限于当前方法。

定义格式:

public class Outer2 {
		private String name = "张三";
		
		public void fun() {
		    int num = 1;		//局部变量,默认final修饰
			
		    class Inside2{		//局部内部类,
				 private String name ="李四";
//				 private  Static int a =2;   //不允许使用 static修饰符
				 public void insideFun() {
//				 	num = 2;  不能修改
					System.out.println(name);   //李四
				}
			 }
		   Inside2 in2 = new Inside2();  //实例化局部内部类
		   in2.insideFun();
		    
		}	
}

测试:

	public static void main(String[] args) {
				Outer2 ou2 = new Outer2();  
				ou2.fun();		//调用fun方法
		}

注意事项:
由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类也不能使用控制符合static修饰符修饰.
且局部变量必须使用final修饰,jdk1.8后默认使用final修饰;局部内部类只能使用abstract 或final修饰。
3.静态内部类

静态内部类: 使用static关键字修饰,不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。

定义格式:

public class Outer1 {
	private  String name ="外部类属性";
	
	
	static class Inside1{     //静态内部类
		private static String name = "静态内部类属性";
		
		public static void fun() {
			//访问静态内部类属性
			System.out.println(Inside1.name);	//打印静态内部类
			//访问外部类属性,必须先实例化外部类,再进行调用
			Outer1 outer1 = new Outer1();
			System.out.println(outer1.name);	//打印外部类属性			
		}
		public void show() {
			System.out.println("静态内部类普通方法");
		}
	}
}

测试:

public static void main(String[] args) {
			//如果静态内部类中为普通方法,则需创建静态内部类实例对象调用
			Inside1 in1 = new Inside1();
			in1.show();
			//静态方法直接通过类名调用
			Inside1.fun();
	}

注意事项:
静态加载总是比非静态的快,即静态内部类中不能直接访问外部类属性,必须先实例化外部类进行调用;在main方法中,可直接通过静态内部类类名进行访问静态方法;如果访问非静态方法,则必须先实例化对象。

4.匿名内部类(常用)

匿名内部类: 即没有名字的内部类,其特征和局部类内部类相同。

使用前提:必须先继承一个父类或实现一个接口
定义格式:
例如实现一个USB接口运转功能

//定义一个接口
public interface InterUsb {
	void run();  //读入功能
}
//定义一个电脑类插入接口功能
public class Comeper {
	
	public void reed(InterUsb interUsb) {   //实现usb接口具体读入功能
			interUsb.run();
	}
}

测试类:

public class TestUsb {
		public static void main(String[] args) {
//			使用匿名内部类实现接口功能,从而省略接口的实现类定义
				InterUsb  inter = new InterUsb() {	
					@Override
					public void run() {
						System.out.println("接口开始运转");
					}
				};
				inter.run();
		}
}
格式:
     new 接口名{
    // 重写方法
}

当只实现某一接口功能,且只使用一次时,可以采用匿名内部类的方法进行实现,从而减少了,实现类的单独定义,减少了开发中的代码量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值