常用类--内部类

内部类分为成员内部类、静态内部类、局部内部类和匿名内部类。它们可以直接访问外部类的私有成员,提供了封装的扩展。成员内部类不能定义静态成员,而静态内部类可以。局部内部类和匿名内部类通常用于一次性实现特定行为,如重写父类或接口的方法。
摘要由CSDN通过智能技术生成

一、内部类概述

1、什么是内部类

定义在一个类的内部的类,就是所谓的内部类

比如类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

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

编译后

Outer$Inner .class
Outer.class

2、内部类的特点

➢编译之后可生成独立的字节码文件。
内部类可直接访问外部类的私有成员,而不破坏封装
➢可为外部类提供必要的内部功能组件。

3、内部类的分类

➢定义在类的内部:

成员内部类、静态内部类

➢定义在类的方法内部:

局部内部类、匿名内部类

内部类分类演示

1、成员内部类

  • 1、定义在类的内部,并且和成员属性、成员方法同一级;
  • 2、成员内部类可以正常访问外部类的资源,不管是否是静态;
  • 3、成员内部类中可以和外部类中所定义的变量重复,但是注意
  • 如果在内部类中使用该重名的资源的话,是就近原则;
  • 4、成员内部类里面不可以定义静态资源;
  • 5、外部类想访问成员内部类的资源的话,需要先通过外部类的对象
  • 来.new 内部类才能获取到内部类对象!

1.在类的内部定义,与实例变量、实例方法同级别的类;
2.内部类中的变量可以和外部类重名;
3.内部类中不能定义static修饰的成员资源,但是可以定义常量;

public class MemberInnerClass {
	//成员属性
	int a = 100;
	//定义一个静态资源
	static int b = 200;
	
	//成员方法
	public void test() {
		System.out.println("这是外部类的成员方法");
	}
	//静态方法
	public static void test1() {
		System.out.println("这是外部类所定义的静态方法");
	}
	//定义一个成员内部类
	class Inner{
		//尝试访问外部类的资源
//		int x = a;//能够正常访问外部类的资源
		//尝试定义一个和外部类的属性名重名的变量,就近原则
		String a = "abc";
		//尝试在内部类里面定义静态资源
//		static int x = 10;//不允许定义
//		public static void test4() {
//			
//		}
		//允许你定义常量
		static final int MAX_VALUE=1000;
		//尝试定义一个方法
		public void test2() {
			//可以在内部类中访问外部类的方法,不区分静态不静态
			test();
			test1();
			System.out.println("我是内部类的方法");
		}
	}
	public void test7() {
		Inner inner = new Inner();
	}
}
class Test{
	//尝试在外部类中访问内部类的资源
	public static void main(String[] args) {
		MemberInnerClass outer = new MemberInnerClass();
		MemberInnerClass.Inner inner = outer.new Inner();
		//访问里面的资源
		System.out.println(inner.a);
		inner.test2();
		System.out.println(MemberInnerClass.Inner.MAX_VALUE);
	}
}

2、静态内部类

  • 静态内部类
  • 1、静态内部类在使用和访问上和成员内部类的唯一区别就是
  • 它具备了静态的特点;
  • 2、在其他类中想访问外部类中的静态类里面的非静态资源,就是需要
  • 来构建一个静态类的对象,但是因为它具备了静态的特点,所以我们只
  • 需要通过外部类.静态内部类就可以来构建对象;
public class StaticInnerClass {
	//定义一些外部类资源
	int a = 100;
	static int b = 200;
	public void test1() {
		System.out.println("我是外部类的成员方法");
	}
	public static void test2() {
		System.out.println("我是外部类的静态方法");
	}
	//定义一个静态内部类
	static class Inner{
		//尝试访问外部类资源
//		int x1 = a;//无法访问非静态资源
		int x2 = b;
		//是否允许和外部类资源同名
		static int a = 1000;//允许同名
		//定义一个普通方法
		public void test3() {
			//访问外部类的方法
//			test1();//不能访问非静态资源方法
			test2();
			System.out.println("这是内部类的普通方法");
		}
		public static void test4() {
			System.out.println("这是内部类的静态方法");
		}
	}
	public void test5() {
		System.out.println(Inner.a);
		Inner.test4();
		Inner inner = new Inner();
		System.out.println(inner.x2);
		inner.test3();
	}
}
class Test2{
	public static void main(String[] args) {
		//在其他类中访问另外一个类的静态内部类中的静态资源
		System.out.println(StaticInnerClass.Inner.a);
		StaticInnerClass.Inner.test4();
		//在其他类中访问另外一个类的静态内部类中的非静态资源
		StaticInnerClass.Inner outer = new StaticInnerClass.Inner();
		System.out.println(outer.a);
		outer.test3();
	}
}

3、局部内部类

  • 局部内部类的使用
  • 1、所谓的局部内部类就是定义在方法里面的类,这个类像局部变量一样
  • 所以,就叫局部内部类
  • 2、局部内部类定义出来就是在当前方法有效,除了该方法,都不能正常访问;
public class LocalInnerClass {
	public static void main(String[] args) {
		//jdk1.8之前想在局部内部类中访问外部类资源,外部类资源必须要加final修饰
//		final int a = 100;
		int a = 100;
		class Inner{
			//访问外部类资源
			int x = a;
			int b = 200;
			public void test1() {
				System.out.println(123);
			}
		}
		//构建一个局部内部类的对象
		Inner inner = new Inner();
		inner.test1();
		System.out.println(inner.b);
	}
	//局部内部类出了定义的方法,哪怕还在外部类的内部都无法进行访问
}
class Test3{
	//局部内部类是无法在类的外边进行访问的
}

4、匿名内部类 重点

匿名内部类

1、匿名内部类是一个特殊的局部内部类,即,它是一个没有类名的局部内部类;

2、跟局部内部类一样,它都是定义在方法内部的类,既然是定义在方法的内部,

那么它的作用就肯定不是为了封装,而是为了实现某个特定的行为动作

那么如果说是个新类的行为动作的话,我们没有必要定义在内部,而是直接单独去定义这个类就行了,因为这个类以后还会用得上,只有一种情况,就是这个类我们只需要使用一次就不再用了,即作为一个子类重写父类的某个方法,该方法重写之后,立马使用,且只使用一次,下次想再次使用,那么业务逻辑会跟这次的不一样,需要重写继承

3、先定义出几个父类:普通的类、接口、抽象类

1、父类 对象 = new 父类(){ 重写父类中的方法 };

使用匿名内部类,直接重写父类的方法,省去创建子类继承父类的过程和创建子类对象的过程。

class F1{
	public void test1() {
		System.out.println("这是父类F1的test1方法");
	}
}

public class NoNameInnerClass {
	public static void main(String[] args) {
		//构建了一个局部内部类,继承F1这个父类,并且重写它的test1方法
		F1 f1 = new F1() {
			public void test1() {
				System.out.println("这是局部内部类,F1的子类");
			};
		};
}


2、接口 对象=new 接口(){ 重写接口中的方法 };

使用匿名内部类,直接重写接口中的方法,省去创建实现类实现接口的过程和创建实现类对象的过程。

interface F3{
	public void test3();
}

public class NoNameInnerClass {
	public static void main(String[] args) {

		//再次使用匿名内部类来重写F3接口中的抽象方法
		new F3() {
			public void test3() {
				System.out.println("这是匿名内部类,F3的子类");
			}
		}.test3();
	}
}

3、抽象类 对象=new 抽象类(){ 重写抽象类中的方法 };

使用匿名内部类,直接重写抽象类中的方法,省去创建实现类实现抽象类的过程和创建实现类对象的过程。

abstract class F2{
	public abstract void test2();
}
public class NoNameInnerClass {
	public static void main(String[] args) {
		//使用匿名内部类来重写F2类的方法
		new F2() {
			public void test2() {
				System.out.println("这是匿名内部类,F2的子类");
			}
		}.test2();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值