在第一次把Java 编程思想中的内部类这一章撸完后,有点印象。大概知道了什么时内部类,局部内部类,匿名内部类,嵌套内部类。随着时间的推移,自己慢慢的就忘记了,总感觉自己思考的东西不多,于是
看了第二遍,并把自己的想法和一些笔记写下来。供以后参考。
定义:如果把A类定义再B类里面,那么把A类叫做 内部类
代码如下:
public class B { public class A{} }这样看内部类是不是感觉很简单?定义确实很简单,但是思考一下,这样定义一个内部类有什么意义吗?或者说能带来什么好处? 上面那样定义,个人感觉是意义不大。所以 ,我们一般定义内部类,都是需要内部类实现一个接口或着抽象类。有实际意义的代码如下(例子来自,java编程思想):
/** * @ClassName Selector * @Description 选择器 * @Author ouyangkang * @Date 2019-03-12 14:21 **/ public interface Selector { // 是否结束 boolean end(); // 当前数据 Object current(); // 下一个节点 void next(); } /** * @ClassName Squence * @Description TODO * @Author ouyangkang * @Date 2019-03-12 14:24 **/ public class Squence { private Object[] items; private int next; public Squence(int size) { items = new Object[size]; } public void add(Object x) { if (next < items.length) { items[next++] = x; } } private class SequceneSelector implements Selector { private int i; @Override public boolean end() { return i == items.length; } @Override public Object current() { return items[i]; } @Override public void next() { if (i < items.length) { i++; } } } public Selector selector(){ return new SequceneSelector(); } } class Test{ public static void main(String[] args) { Squence squence = new Squence(10); for (int i = 0; i < 10 ; i++) { squence.add(i); } // 调用内部类 这是迭代器模式的一个例子。 通过内部类 ,访问类中的私有属性。 Selector selector = squence.selector(); while (!selector.end()){ System.out.print(selector.current()+" "); selector.next(); } } }输出: 0 1 2 3 4 5 6 7 8 9
请仔细查看上面代码。 这是个非常好的例子。访问权限为 private 的内部类 SequceneSelector 实现了 Selector 接口 ,该内部类可以访问外部类 Squence 中私有属性 items 。 并提供一个公开的方法 selector ,返回一个,向上转型为 Selector 类型。 在测试代码中。先创建 squence 对象。 往里面添加10个元素。 并调用该对象的中的 selector() 方法,返回一个 Selector 类型的对象。 根据我们定义的 Selector 接口中方法的含义,编码。打印输出。
上面代码说明了内部类的几个好处:
隐藏了细节,实现一个接口,向上转型。
可以访问外部类中的所有私有属性,方法。就像是拥有他们一样。但是不是拥有(你可以把它想成一个成员方法)
我觉得第一点没什么好说的,反倒是第二点,自己是这样理解的:外部类就像是一个房子,里面的成员变量,方法,内部类。就像是房子里面的人。可以相互通信。而内部类实现了一个接口或着抽象类后,就有点像细作一样,表面看起来是房子里面的人,其实真正是外面的人。只要我创建它,并通过向上转型,就可以到外面去通信。
局部内部类定义: 如果把A类定义再B类的方法中,那么把A类叫做局部内部类
代码如下:
public class A { private void getB(){ class B{} } }其实上面代码意义并不大。 下面看下一些有意义的代码。代码如下:
/** * @InterfaceName Destination * @Description TODO * @Author ouyangkang * @Date 2019-03-12 19:59 **/ public interface Destination { String readLabel(); } /** * @ClassName Parcel * @Description TODO * @Author ouyangkang * @Date 2019-03-12 20:00 **/ public class Parcel { public Destination destination(String str){ class PDestination implements Destination{ private String label = str; public PDestination(String label){ this.label = label; } @Override public String readLabel() { return label; } } return new PDestination(str); } public static void main(String[] args) { Parcel parcel = new Parcel(); Destination destination = parcel.destination("hello"); System.out.println(destination.readLabel()); } }输出 hello
定义一个为 Destination 的接口,方法为 readLabel() 。 Parcel 类中定义了一个 返回 Destination 类型的方法。 该方法中定义了一个 PDestination 类,并实现了 Destination 接口。 在最后返回PDestination 的对象。 上面局部内部类很熟悉把。下面,我们看下匿名内部类。
匿名内部类将上面Parcel类修改 ,代码如下
/** * @ClassName Parcel1 * @Description TODO * @Author ouyangkang * @Date 2019-03-13 15:33 **/ public class Parcel1 { public Destination destination(final String str){ return new Destination() { private String label = str; @Override public String readLabel() { return label; } }; } public static void main(String[] args) { Parcel1 parcel1 = new Parcel1(); Destination ouyangkang = parcel1.destination("hello"); System.out.println(ouyangkang.readLabel()); } }输出:hello