java内部类整理

java 内部类为java提供的语法,有必要掌握,我这里是基于JDK8,版本不一样语法可能有变化,如final变化

内部类基本使用

定义内部类

public class Outer {
	
	private int x = 10;
	
	public void print() {
		System.out.println(x);
	}

	public class Inner {
		private int y = 2;
		
		public void printXY() {
			System.out.println(String.format("[%s,%s]", x, y));
			x = 5;
			y = 5;
			System.out.println(String.format("[%s,%s]", x, y));
		}
	}
	
}

内部类的一些概念

  1. Outer为外部类,Inner为内部类。
  2. Inner可以直接使用Outer所有公有私有属性方法
  3. Inner内部类实例化对象必须依赖于Outer外部类实例化对象创建

实例化演示

public class OuterTest {

	public static void main(String[] args) {
		// 实例化外部类
		Outer outer = new Outer();
		outer.print();
		
		// 通过外部类才能实例化内部类
		Outer.Inner inner = outer.new Inner();
		inner.printXY();
	}

}

除了上述显示outer.new Inner()创建,还可以隐式创建,添加生成内部类方法

public class Outer2 {
	
	private int x = 10;
	
	public void print() {
		System.out.println(x);
	}

	public class Inner {
		private int y = 2;
		
		public void printXY() {
			System.out.println(String.format("[%s,%s]", x, y));
			x = 5;
			y = 5;
			System.out.println(String.format("[%s,%s]", x, y));
		}
	}
	
	/**
	 * 隐式生成内部类
	 */
	public Inner inner() {
		// return this.new Inner();   实质上有一个this对象
		return new Inner();
	}
	
}

实例化演示

public class Outer2Test {

	public static void main(String[] args) {
		// 实例化外部类
		Outer2 outer = new Outer2();
		outer.print();
		
		// 通过外部类才能实例化内部类
		Outer2.Inner inner = outer.inner();
		inner.printXY();
	}

}

内部类实际使用例子一

当前使用内部类的作用是减少参数传递编写一个数组的迭代器

未使用内部类

数组集合

public class MyList {
	
	private int index = 0;
	private Object[] datas;
	
	public MyList(int size) {
		datas = new Object[size];
	}
	
	public void add(Object o) {
		datas[index++] = o;
	}
	
	public int getIndex() {
		return index;
	}
	
	public Object[] getDatas() {
		return datas;
	}
	
}	

迭代器

import java.util.Iterator;

public class MyListIterator implements Iterator<Object>{
	// 记录原始数据
	private int index = 0;
	private Object[] datas;
	// 游标器
	private int begin = 0;
	
	public MyListIterator(MyList list) {
		this.index = list.getIndex();
		this.datas = list.getDatas();
	}

	@Override
	public boolean hasNext() {
		return begin < index;
	}

	@Override
	public Object next() {
		return datas[begin++];
	}

}

测试代码

public class MyListTest {

	public static void main(String[] args) {
		
		// 创建对象并初始化数据
		MyList list = new MyList(10);
		list.add(1234);
		list.add("张三");
		list.add(11.22f);
		
		// 转换为迭代器
		Iterator<Object> iterator = new MyListIterator(list);
		while (iterator.hasNext()) {
			Object value = iterator.next();
			System.out.println(value);
		}
	}

}

测试值

1234
张三
11.22

使用内部类
public class MyList2Iterator {
	
	private int index = 0;
	private Object[] datas;
	
	public MyList2Iterator(int size) {
		datas = new Object[size];
	}
	
	public void add(Object o) {
		datas[index++] = o;
	}
	
	public Iterator<Object> iterator() {
		return new InnerMyListIterator();
	}
	
	// 省略参数传递的代码,内部类可以直接使用外部类变量
	// class 申明为private,类专用
	private class InnerMyListIterator implements Iterator<Object>{
		// 游标器
		private int begin = 0;

		@Override
		public boolean hasNext() {
			return begin < index;
		}

		@Override
		public Object next() {
			return datas[begin++];
		}
	}
}	

测试代码

public class MyList2IteratorTest {
	public static void main(String[] args) {
		// 创建对象并初始化数据
		MyList2Iterator list = new MyList2Iterator(10);
		list.add(1234);
		list.add("张三");
		list.add(11.22f);

		// 转换为迭代器
		Iterator<Object> iterator = list.iterator();
		while (iterator.hasNext()) {
			Object value = iterator.next();
			System.out.println(value);
		}
	}

}

匿名内部类构造函数

定义一个接口

public interface MyInterfaces {
	void sayhello(String name);
}

无参数演示

public class Caller {

	public MyInterfaces myInterfaces(int x) {
		// 匿名内部类是没有构造函数的,这里是无参数传入
		return new MyInterfaces() {
			@Override
			public void sayhello(String name) {
				System.out.println(name + x);
			}
			
		};
	}
	
	public static void main(String[] args) {
		Caller caller = new Caller();
		MyInterfaces myInterfaces = caller.myInterfaces(1234);
		myInterfaces.sayhello("王丽");
	}
}

有参数赋值

package test.inner;


public class Caller {

	public MyInterfaces myInterfaces(int x) {
		
		// 匿名内部类是没有构造函数的,这里是无参数传入
		return new MyInterfaces() {
			
			private int y = x;
			
			// 或者以下写法
			/*{
				y = x;
			}*/
			
			@Override
			public void sayhello(String name) {
				// x = 2;  error 不属于外部类变量不允许内部类更改
				y = 3;
				System.out.println(name + x + y);
			}
			
		};
	}
	
	public static void main(String[] args) {
		Caller caller = new Caller();
		MyInterfaces myInterfaces = caller.myInterfaces(1234);
		myInterfaces.sayhello("王丽");
	}
}

嵌套类(静态内部类)

有层次关系的独立类

嵌套类定义

public class StaticInner {

	private int x;
	
	public static class Inner {
		private int y ;

		public int getY() {
			return y;
		}

		public void setY(int y) {
			this.y = y;
		}
		
		@Override
		public String toString() {
			// x = 2;  error static 修饰可理解为StaticInner下独立的其他类
			return y + "";
		}
	}
	
}

实例化

/**
 * 
 * 两种没有除了层次关系没有任何联系
 */
public class StaticInnerTest {

	public static void main(String[] args) {
		StaticInner staticInner = new StaticInner();

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

}

内部类的继承

静态类的继承必须先实例化外部类

定义一个静态类

public class Outer {
	
	private int x = 10;
	
	public void print() {
		System.out.println(x);
	}

	public class Inner {
		private int y = 2;
		
		public void printXY() {
			System.out.println(String.format("[%s,%s]", x, y));
			x = 5;
			y = 5;
			System.out.println(String.format("[%s,%s]", x, y));
		}
	}
	
}

继承演示

public class SubOuterInner extends Outer.Inner {

	public SubOuterInner(Outer outer) {
		// 下面这行代码必须有,不然报错
		outer.super();
	}
	
}

内部类与final关系

在jdk8中,内部类可以访问修改外部类的任何变量,但是不得修改外部类的方法入参,以及方法内定义的临时变量。jdk8不用显示使用final修饰

其中yyy = 22;错误,不得修改外部类的方法入参z = 2342;错误,方法内的临时变量

public class Outer3 {
	
	private int x = 10;
	
	public void print(int yyy) {
		class Inner {
			public void f() {
				x = 11;
				System.out.println(x);
				// yyy = 22;   error
				// z = 2342;   error
			}
		}
	}
}
实际常发生的错误

以下代码错误,内部类修改方法内的临时变量

public class TestThread {
	public void main(String[] args) {
		
		int x = 11;
		
		/**
		 * 定义一个匿名内部类
		 */
		Runnable runnabel = new Runnable() {
			public void run() {
				System.out.println(x);
				// x = 1234; error
			}
		};

	}
}

将局部变量声明到外部类变量即可修改,请注意

public class TestThread {
	int x = 11;
	public void main(String[] args) {
		/**
		 * 定义一个匿名内部类
		 */
		Runnable runnabel = new Runnable() {
			public void run() {
				System.out.println(x);
				x = 1234; 
			}
		};
	}
}

内部类多继承弥补

可以任意继承类数量

package test.inner;

class A{
	public void f() {
		System.out.println("f");
	}
}
class B{
	public void g() {
		System.out.println("g");
		 x();
	}
	public void x() {
		System.out.println("g");
	}
}

// 继承A
public class Test extends A {
	
	// 继承B
	class TestB extends B {}
	
	// 持有B对象的引用
	B createB() {
		return new TestB();
	}
	
	// test对象能够转换为A,B超类
	public static void main(String[] args) {
		Test test = new Test();
		A a = test;
		B b = test.createB();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值