今天的内容:
定义在类的内部。
作用:不希望该类作为大家共同访问的类,只供本类使用,当作本类的一个成员使用。
类别:成员内部类、局部内部类、静态内部类、匿名内部类
内部类是一个编译时的概念,一旦编译成功就会成为完全不同的两个类,对于一个名为outer的外部类和其内部定义的名为inner的内部类,编译完成后会出现outer.class 和 outer$inner.class两类。 所以内部类的成员变量、方法名可以和外部类相同。
成员内部类:
作为外部类的成员,可以直接使用外部类的所有成员和方法。即使是private的。如果外部类要访问内部类的成员和方法,则需要通过内部类的对象来获取。注意:成员内部类不能还有static的变量的方法。因为成员内部类需要先创建了外部类,才能创建它自己的内部类。
代码如下:
package some; public class some{ private int x = 5; public static void main(String[] args) { some s = new some(); some.Inner in = s.new Inner(); in.inner(); } public void out() { System.out.println("外部类 out()"); } public class Inner{ int x = 10; public void inner() { out(); System.out.println("内部类 Inner(),x = " + x); } } }
静态内部类:
嵌套内部类就是修饰为static的内部类。声明为static的内部类。不需要内部类对象和外部类对象的联系。即用户不需要创建内部类对象和外部类对象。可以直接引用 外部类.内部类。
嵌套类和普通内部类的区别:前者可有static数据和static属性。但是后者则不能。另外嵌套类不能生命为private。一般为public,方便调用。
package some; interface Question{ public boolean check(); } public class some{ public static void main(String[] args) { some.Inner in = new some.Inner(); in.check(); } public static class Inner implements Question{ @Override public boolean check() { System.out.println("check..."); return false; } } }
局部内部类:
定义在方法和作用域内的内部类。即在方法中定义的内部类成为局部内部类参考局部变量。注意:局部内部类不能有访问修饰符。因为他不是外围类的一部分,但是它可以访问当前代码块内的常量和此外围类所有的成员。
局部内部类定义在方法中,当方法执行完毕后则会被JVM回收。局部内部类的实例化只能在方法中进行。
package some; public interface Type{ public double area(); } public class some{ public static void main(String[] args) { some s= new some(); s.test(); } public void test() { final double pi=3.14; int r = 6; class Circle implements Type{ public double area() { return pi*r*r; } } Circle c = new Circle(); System.out.println("area="+c.area()); } }
匿名内部类:
不能有名称的类,所以没有办法引用他们,必须在创建时,作为new语句的一部分来声明他们。需要采用另一种形式的new语句。
即:new <类或接口> <类的主体>
这种形式的new语句声明一个新的匿名类,对一个给定的类进行扩展或者实现一个给定的接口。如果匿名类实现了一个接口,它的主体必须实现接口的方法.
匿名内部类形式如下:
new 类或接口{ //方法主体 }
匿名内部类的使用示例:
package some; interface T{ public void t(); } public class some{ public static void main(String[] args) { T t = new T() { public void t() { System.out.println("t...."); } }; t.t(); } }
匿名内部类作为方法的参数传递:
package some; interface T{ public void t(); } public class some{ public static void main(String[] args) { some s = new some(); s.say/*传递参数括号的开始*/(new T(){ @Override public void t() { System.out.println("t....."); } }/*传递参数括号的结束*/); } public void say(T t) { t.t(); } }
匿名内部类作为返回值
package some; interface T{ public void t(); } public class some{ public static void main(String[] args) { some s = new some(); s.get(); } public T get() { return new T() { @Override public void t() { System.out.println("t"); } };//注意分号,return语句结束 } }
注意:
匿名类的声明是在编译时进行的,实例化却是在运行时进行
- 使用匿名内部类的原则:
- 不能有构造方法
- 不能定义任何静态的成员、方法和类
- 不能是public、protected、private、static的
- 只能创建一个匿名内部类的实例
- 一个匿名类一定是在new后面,用其隐含实现一个接口或者一个类
- 局部内部类的所有限制都对其生效
- 内部类只能访问外部类的静态变量或静态方法
- 内部类当中的this指的是匿名内部类本身。如使用外部类中的this,则“外部类.this”
明天的打算:继续学习
问题:无