java基础:内部类

思维导图

在这里插入图片描述

概念

1、定义

简单来说就是在类的内部再定义一个类

2、形式

//外部类
class Outer{
	//...
	//内部类
	class Inner{
		//...
	}
}

分类

1、成员内部类

1.1 特征

定义在类中,方法外

1.2 特性

1、编译成功后会生成两个class文件

MemberOuterClass.class
MemberOuterClass$MemberInnerClass.class

2、成员内部类中不能编写静态的属性和方法

原因:在类加载的时候,被static修饰的静态变量就会被初始化,静态方法就会被调用,如果在内部类中定义静态变量和静态方法,就会导致不需要外部类的对象就可以生成内部类的对象,这与成员内部类的定义相驳。

3、成员内部类的对象必须通过外部类的对象才能创建
4、成员内部类和外部类的相互访问
(1)成员内部类访问外部的属性和方法

  • 内部类调用自身属性-----直接用
  • 内部类调用自身方法-----this.方法名
  • 内部类调用外部类非静态属性-----外部类类名.this.属性名
  • 内部类调用外部类非静态方法-----外部类类名.this.方法名
  • 内部类调用外部类静态属性-----外部类类名.方法名
  • 内部类调用外部类静态方法-----外部类类名.方法名
public class MemberOuterClass {
	//外部类属性
	private String name; 
	private static int age; 
	
	//外部类的方法
	public void run() {
		
	}
	
	public static void go(){
		
	}
	
	//成员内部类
	public class MemberInnerClass{
		
		private String name;
		private int age;
		
		public void run(String name) {
			//访问当前run方法中的参数name
			System.out.println(name);
			//访问内部类自己的属性name
			System.out.println(this.name);
			
			//访问外部类的非静态属性
			System.out.println(MemberOuterClass.this.name);
			//访问外部类的静态属性
			System.out.println(MemberOuterClass.age);
			
			//访问外部类的非静态方法
			MemberOuterClass.this.run();
			//访问外部类的静态方法
			MemberOuterClass.go();
		}
	}
	//成员内部类声明结束
}

(2)外部类访问成员内部类的属性和方法

  • 通过创建外部类的对象,可以直接调用成员内部类的属性和方法
public class MemberOuterClass {
	//外部类方法
	public void test() {
		MemberInnerClass m = new MemberInnerClass();
		
		//外部类访问成员内部类的属性
		System.out.println(m.name);
		System.out.println(m.age);
		
		//外部类访问成员内部类的方法
		m.run("tom");
	}
	
	//声明成员内部类
	public class MemberInnerClass{
		//定义内部类的属性和方法
		private String name;
		private int age;
		
		public void run(String name) {
			
		}
	}
}

(3)在其他类中使用这个内部类

  • 前提是这个成员内部类不是被private修饰
  • 这个内部类需要import导入,形式:import 外部类.内部类
  • 创建对象时,需先创建外部类对象,再使用外部类对象再创建内部类对象:外部类对象.new 内部类对象();

2、静态内部类

2.1 特征

内部类被static修饰,也只有内部类能被static修饰,其他类不能被static修饰

2.2 特性

1、编译后生成两个class文件

staticOuterClass.class 外部类
staticOuterClass$staticInnerClass.class 静态内部类

2、静态内部类内可以编写属性和静态方法,并且四种内部类中只有静态内部类可以编写静态属性和静态方法
3、静态内部类与外部类的相互访问
(1)静态内部类访问外部类的属性和方法

  • 静态内部类中访问不了外部类中的非静态属性和方法
  • 内部类访问自身的属性和方法-----this.方法名/属性名
  • 内部类访问自身的静态属性和方法-----直接使用
  • 内部类访问外部类的静态属性和方法-----外部类类名.属性名/方法名

public class StaticOuterClass {
	private String name; //外部类中的非静态属性
	private static int age; //外部类中的静态属性
	
	public void run() {} //外部类非静态方法
	public static void go()	{} //外部类静态方法
	
	//声明静态内部类
	public static class StaticInnerClass{
		private String name;
		private static int age;
		
		public void run(String name) {
			//访问当前run方法中的参数name
			System.out.println(name); 
			//访问内部类自己的属性
			System.out.println(this.name);
			//访问内部类自己的静态属性
			System.out.println(age);
			
			//静态内部类中无法访问外部类的非静态属性和方法
			
			//访问外部类的静态属性和方法
			System.out.println(StaticOuterClass.age);
			StaticOuterClass.go();
		}
	}
}

(2)在其他类中访问这个非private修饰的静态内部类

  • 需要import导入,形式:import 外部类.内部类
  • 创建对象时,直接:new 静态内部类对象();不再需要外部类对象

4、静态类与普通内部类的区别
普通内部类

1、内部类拥有普通类的所有特性,也拥有类成员变量的特性
2、内部类可以访问其外部类的成员变量,属性,方法,其它内部类

静态内部类

1、只有内部类才能声明为static,也可以说是静态内部类
2、只有静态内部类才能拥有静态成员,普通内部类只能定义普通成员
3、静态类跟静态方法一样,只能访问其外部类的静态成员
4、如果在外部类的静态方法中访问内部类,这时候只能访问静态内部类

3、局部内部类

3.1 特征

定义在外部类的方法中。

3.2 特性

1、局部内部类的作用范围只在当前方法中
2、最不常用。。。
3、局部内部类与外部类的相互访问
(1)局部内部类访问外部的属性和方法

public class LocalOuterClass {
	
	private String name; //非静态变量
	private static int age; //静态变量
	
	//外部类方法
	public void run() {} //非静态方法
	public static void go() {} //静态方法
	
	public void sayHello(String name) {
		//开始声明局部内部类
		class LocalInnerClass{
			private String name;
			public void test(String name) {
				//访问当前test()方法中的参数name
				System.out.println(name);
				//访问内部类自身的属性
				System.out.println(this.name);
				
				//访问外部类的非静态属性
				System.out.println(LocalOuterClass.this.name);
				
				//访问外部类的非静态方法
				LocalOuterClass.this.run();
				
				//访问外部类的的静态属性和方法
				System.out.println(LocalOuterClass.age);
				LocalOuterClass.go();
			}
		}
	}
}

(2)局部类内中访问当前方法中的变量(这个变量必须是final修饰的)

public void sayHello(final String name) {
			final int num = 1;
			class LocalInnerClass{
				public void test() {
					System.out.println(name);
					System.out.println(num);
					
					//final修饰的变量只能被赋值一次
					//name = "tom";
					//num = 2;
					
				}
		}
}

在JDK1.8中,一个局部变量在局部内部类中进行访问了,那这个变量自动变为final修饰

(3)外部类访问局部内部类的属性和方法

public void sayHello(String name) {
		//开始声明局部内部类
		class LocalInnerClass{
			private int num;
			public void test() {
				
			}
		}
		//创建局部内部类对象
		LocalInnerClass lic = new LocalInnerClass();
		//对象访问属性
		System.out.println(lic.num);
		//对象调用方法
		lic.test();
	}

4、匿名内部类

4.1 特征

没有名字的类,使用匿名内部类可以简化实现接口和抽象方法重写的过程。

匿名内部类的一般格式:

父类或者接口类型 变量名 = new 父类或者接口(){
	//方法重写
	@Override
	public void method(){
		//执行语句
	}
};   //注意别落下了这个分号

//调用实现(重写)后的方法
变量名.method();

4.2 特性

1、匿名内部类的两种形式

1、利用一个父类,进行声明并创建匿名内部类对象,这个匿名内部类默认就是这个父类的子类型
2、利用一个接口,进行声明并创建匿名内部类对象,这个匿名内部类默认就是这个接口的实现类

2、必须依托于一个父类型或者一个接口
(1)依托父类

//这是一个父类型
abstract class Animal{
	public abstract void run(); //
}
public class Demo01 {
	public static void main(String[] args) {
		Animal animal = new Animal() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类中的默认实现");
			}
			
		};
		
		//匿名内部类方法的通用
		animal.run();
	}
}

(2)依托接口
这个匿名内部类默认就是这个接口的实现类。

interface Action{
	void run();
}
public class Demo {
	public static void main(String[] args) {
		Action a = new Action() { 

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类的默认实现!");
			}};
			
			//匿名内部类的调用
			a.run();
	}
}

3、在声明的同时必须创建对象

4、匿名内部类中无法定义构造器

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值