Java的内部类

1.内部类概述和访问特点

  • 内部类:就是在类内部再声明类

  • 内部类访问特点
    1.内部类可以直接访问外部类的成员,包括私有。
    2.外部类要访问内部类的成员,必须创建对象

  • 内部类对象的创建语法
    1.外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    2.开发中自己声明个内部类比较少用,用的多的就是集合中的遍历

2.内部类的创建

  • 在外部类内部创建:
    和创建普通对象一样
Inner inner = new Inner();
  • 在外部类外部(也就是其他类)创建静态内部类:
    外部类.内部类 内部类对象 = new 外部类.内部类();
//外部类.内部类 内部类对象 = new 外部类.内部类();
Outer.Inner inner = new Outer.Inner();
  • 在外部类外部创建非静态内部类:
    外部类.内部类 内部类对象 = new 外部类().new 内部类();
//外部类.内部类 内部类对象 = new 外部类().new 内部类();
Outer.Inner inner = new Outer().new Inner();

3.内部类分类

成员内部类

  • 顾名思义,相当于外部类的一个成员,成员内部类内部不允许存在任何 static 变量或方法;
public class Tset01 {

	public static void main(String[] args) {

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

class Outer {
	private String str1 = "private...";
	public String str2 = "public...";
	
	class Inner {
//		public static String str3 = "static..."; //报错

		public void test() {//可访问外部属性,方法
			System.out.println(str1);
			System.out.println(str2);
		}
	}
}
  • 内部类问题:
//要求:使用已知的变量,在控制台输出30,20,10。
class Outer {
	public int num = 10;
	class Inner {
		public int num = 20;
		public void show() {
			int num = 30;
			System.out.println(num);
			System.out.println(this.num);
			System.out.println(Outer.this.num);
		}
	}
}
class Test {
	public static void main(String[] args) {
		Outer.Inner inner = new Outer().new Inner();
		inner.show();
	}	
}

局部内部类

类似于局部变量,是存在于方法内的类(方法内部类)

  1. 该内部类不能用访问权限修饰符(public、private、protected 均不允许);
  2. 局部内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问,也就是说如果该方法没有创建对象并调用,那这个内部类就废了;
  3. 局部内部类访问局部变量必须用final修饰
public class Tset01 {

	public static void main(String[] args) {

		Outer outer = new Outer();
		outer.test1();
	}
}

class Outer {

	public void test1() {
		final int a = 10;//局部变量
		
		class Inner {//局部内部类
			public void test2() {
				System.out.println(a);
			}
		}

		Inner inner = new Inner();
		inner.test2();
	}
}

代码内存图:
在这里插入图片描述

  • 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
    因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用
    (JDK8不用写final,不报错)

私有内部类的使用【了解】

public class Tset01 {
	
	public static void main(String[] args) {
		
		Outer out = new Outer();
		out.test1();//输出 Inter test2......
		
	}
}

class Outer{
	int n = 10;
	
	private class Inner{
		//n = 20;	//不能访问,报错
		public void test2(){
			System.out.println("Inter test2......");
		}
	}
	
	public void test1(){
		Inner a = new Inner();
		a.test2();
	}
}

静态内部类的使用 【了解】

  • 成员内部类被静态修饰后的访问方式是:
    外部类名.内部类名 对象名 = 外部类名.内部类对象;
public class Tset01 {

	public static void main(String[] args) {

		Outer.Inner inner = new Outer.Inner();
		inner.test();	//输出:Inner test...
		Outer.Inner1.test();//输出:Inner1 test...
	}
}

class Outer {

	static class Inner {
		public void test() {
			System.out.println("Inner test...");
		}
	}

	static class Inner1 {
		public static void test() {
			System.out.println("Inner1 test...");
		}
	}
}

匿名内部类

  • 匿名内部类就是内部类的简化写法,是一个没有名字的方法内部类,特点和方法与方法内部类完全一致。

  • 写匿名内部类前提是存在一个抽象类或者接口
    匿名内部类没有类名,因此没有构造方法。

  • 匿名内部类格式:
    new 抽象类或者接口名(){ 重写方法; }

  • 匿名内部类本质是什么呢?
    是一个继承了该类或者实现了该接口的子类匿名对象

  • 匿名内部类的特点
    匿名内部类必须实现接口的所有方法
    匿名内部类必须实现抽象类的所有方法

  • 匿名内部类的方法调用
    像普通对象一样,调用方法即可

public class Tset01 {

	public static void main(String[] args) {
		//匿名内部类,就相当于是抽象类的子类
		new Inner() {//匿名内部类,实现所有抽象方法
			
			@Override
			public void test() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类	...");
			}
		}.test();
		
		//也可以将匿名类赋给对象,这样可以多次执行方法
		Inner inner = new Inner() {
			
			@Override
			public void test() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类	...1");
			}
		};
		inner.test();
	}
}

abstract class Inner{//抽象类
	public abstract void test();
}

使用匿名内部类的代码补全:

//要求在控制台输出”HelloWorld”
interface Inner { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
	public static void main(String[] args) {
		  Outer.method().show();
	  }
}

==========================================
class Outer { //补齐代码
	
	public static Inner method() {
		return new Inner() {
			
			@Override
			public void show() {
				// TODO Auto-generated method stub
				System.out.println("HelloWorld");
			}
		};
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值