内部类
所谓内部类就是定义在一个类内部的类,内部类的概念是在JDK1.1中被引用的,引入内部类主要有以下一些考虑:
*内部类对象能访问它所处类的私有数据
*内部类能够隐藏起来不为同一个包中的其他类访问
*匿名内部类可以方便地用在回调方法中,典型应用是java(android)图形编程中的事件处理
1.成员内部类,顾名思义,是一个可以看成是外部类的非静态成员的内部类,成员内部类和普通的成员没什么区别,可以与普通成员一样修饰和限制。它具有以下特点:
*成员内部类可以访问外部类的私有成员或属性
*外部类不能访问成员内部类中的私有属性
*成员内部类是一个编译时的概念,一旦编译成功,就会成为与外部类完全不同的类
*内部类和外部类在编译时是两个不同的类,内部类对外部类没有任何依赖
内部类和外部类可以相互访问,首先在外部类的内部可以创建内部类的对象并直接使用:
Inner i = new Inner();
在外部类的外部需要先建立一个外部类对象,然后再生成一个内部类对象,这是因为内部类相当于外部类的成员,而成员只有在所属对象存在的情况下才存在:
Outer.Inter inn =new Outer().new Inter(); 或 Outer.Inter inn = out.newInter();
*内部类可以访问外部类的任何成员
*外部类需要创建内部类的对象才可以访问内部类的成员
package yy; public class OuterA { private String name = "maidou"; private static String address = "Harbin"; public void m1(){ System.out.println("OuterA的方法m1!"); } public class InnerA{ public InnerA(){ } String name = "guai"; public void m2(){ System.out.println("OuterA的name:"+OuterA.this.name); System.out.println("OuterA的address:"+address); System.out.println("OuterA的内部类InnerA的name:"+this.name); } } public static void main(String[] args) { OuterA out = new OuterA(); out.m1(); OuterA.InnerA in = new OuterA().new InnerA(); in.m2(); } } 运行结果: OuterA的方法m1! OuterA的name:maidou OuterA的address:Harbin
2.在方法中定义的内部类成为局部内部类,它是一个只有在局部有效的内部类,局部内部类作用域与变量相同,只在其所在的语句块中有效,所以只能在其有效的位置访问或创建。
*局部内部类的语法规则和成员内部类的语法规则相同,只是局部内部类是被定义在方法中
*与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块
*局部内部类可以访问外部类的私有实例变量和局部final常量
*在外部类的外部不能直接访问局部内部类,这样就有效的保证了局部内部类对外部是不可见的,但是如果在类外不能访问局部内部类,那么局部内部类的意义就要大打折扣了。解决方法是通过局部内部类和接口达到一个强制的弱耦合关系,用局部内部类来实现接口,并在方法中返回接口类型,这样既可以使局部类不可见,屏蔽实现类的可见性,又可以在类的外部访问内部类的方法
package yy; public class OuterBTest { public static void main(String[] args) { OuterB outb = new OuterB(); MyInter obj = outb.m1(); obj.m3(); obj.m4(); } } class OuterB{ private int a = 10; public MyInter m1(){ int b =20; final int c = 30; class InnerB implements MyInter{ public void m3(){ //System.out.println("局部内部类InnerB的m3方法调用局部变量b="+b);不能访问局部非final变量 System.out.println("可访问外部类的私有变量a"+a); } public void m4(){ System.out.println("可访问外部类的局部final变量:"+c); } } return new InnerB(); } } interface MyInter{ public void m3(); public void m4(); } 结果: 可访问外部类的私有变量a10 可访问外部类的局部final变量:30
3.静态内部类其实已经脱离了外部类,在创建静态内部类对象时也不需要外部类对象的存在,其实质是一个放置在别的类内部的普通类,而关键字static也只是说明其在创建对象时不依赖外部类对象的存在,并不是说这个类本身是静态的。
*静态内部类与前面讲的两种非静态内部类的语法基本相同,区别主要在内部类的声明前要加上static关键字,另外,静态内部类也不可以用private进行定义
*与成员内部类和局部内部类恰巧相反,静态内部类只能访问外部类的静态成员,不能访问外部类的非静态成员
*静态内部类的对象可以直接生成,而不需要外部类的对象来生成,这样实际使静态内部类成为了一个顶级类,这主要是因为静态内部类是外部类的静态成员,并不依赖于外部类的对象而存在
* 静态内部类与非静态内部类的区别是本质上的。
package yy; public class OutC { private String name = "maidou"; private static String address = "Harbin"; public static void m1(){ System.out.println("外部类的方法-address:"+address); } public static class InnerC{ public void m2(){ //System.out.println("name"+name);只能调用外部类的static属性 System.out.println("静态内部类InnerC调用OutC的address:"+address); m1(); } } public static void main(String[] args) { OutC.InnerC in = new OutC.InnerC(); in.m2(); } } 输出: 静态内部类InnerC调用OutC的address:Harbin 外部类的方法-address:Harbin
4.匿名内部类是一种特殊的局部内部类,这种内部类没有类名,该类适用于只使用一次而且不需要多次创建的对象的类,使用匿名内部类可以使类代码与创建对象同事完成,这样做不但方便,而且还提高了代码的可维护性。
*没有类名,没有class关键字,没有构造方法,有继承但没有extends关键字,有类体
*大部分匿名内部类用于接口回调
*匿名内部类在编译的时候有系统自动起名
* 匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写package yy; public class OutD { public static void main(String[] args) { AbstractFather af = new AbstractFather() { { count = (int) (100*Math.random()); }//定义语句块 @Override //实现父类的方法 public void m() { System.out.println("您的号码是:"+count); } }; af.m(); } } abstract class AbstractFather{ int count; abstract void m(); } 输出: 您的号码是:27
好了,可以继续昨天的任务啦