读书人

黑马软件工程师_java内部类

发布时间: 2013-03-28 10:20:24 作者: rapoo

黑马程序员_java内部类
??? ??? ??? ??? ??? ??? ??? + OuterClass.this.str);
??? ??? ??? ??? ??? ??? System.out.println("访问内部类成员:" + this.str);
??? ??? ??? ??? ??? ??? System.out.println("访问内部类方法中的局部变量:"
??? ??? ??? ??? ??? ??? ??? + str);
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? ??? /**
??? ??? ??? ??? ?* 创建访问内部类的方法
??? ??? ??? ??? ?*/
??? ??? ??? ??? public void visitInnerClass() //如果加上static修饰,编译不通过
??? ??? ??? ??? {
??? ??? ??? ??? ??? //创建内部类对象
??? ??? ??? ??? ??? InnerClass in = new InnerClass();
??? ??? ??? ??? ??? //调用打印方法
??? ??? ??? ??? ??? in.showField();
??? ??? ??? ??? }
??? ??? ??? ??? public static void main(String[] args) {
??? ??? ??? ??? ??? //创建外部类对象
??? ??? ??? ??? ??? OuterClass oc = new OuterClass();
??? ??? ??? ??? ??? oc.visitInnerClass();
??? ??? ??? ??? }
??? ??? ??? }
??? ??? 编译上面程序,看到在文件所在路径生成了两个class文件,一个是OuterClass.class,
??? ??? 另一个是OuterClass$InnerClass.class,前者是外部类的文件,后者是内部类文件,
??? ??? 即成员内部类(包括静态和非静态)的class文件形式:外部类名$内部类名.class。
??? Java不允许在非静态内部类里定义静态成员,否则编译出错。
??? ??? 演示说明:
??? ??? ??? public class Outer{
??? ??? ??? ??? private class Inner{
??? ??? ??? ??? ??? //下面三个静态声明都将引发编译错误
??? ??? ??? ??? ??? static{}
??? ??? ??? ??? ??? private static int a;
??? ??? ??? ??? ??? private static void show(){}
??? ??? ??? ??? }
??? ??? ??? }
??? 在外部类以外使用非静态内部类,则非静态内部类不能使用private修饰。语法如下:
??? ??? 外部类名.内部类名 标识符 = new 外部类名().new 内部类名();
??? ??? 演示:
??? ??? ??? public class Outer {
??? ??? ??? ??? public class Inner
??? ??? ??? ??? {
??? ??? ??? ??? ??? public void show()
??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? System.out.println("这是内部类");
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? }
??? ??? ??? public class Test{
??? ??? ??? ??? public static void main(String[] args) {
??? ??? ??? ??? ??? //在外部类以外创建内部类对象
??? ??? ??? ??? ??? Outer.Inner in = new Outer().new Inner();
??? ??? ??? ??? ??? in.show();
??? ??? ??? ??? }
??? ??? ??? }
静态内部类:
??? 使用static来修饰的成员内部类称为静态内部类。根据静态成员不能访问非静态的成员的规则,
??? 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员(static修饰)。
??? 即使是在静态内部类的实例方法也不能访问外部类的实例成员。
??? ??? 演示:
??? ??? ??? public class Outer{
??? ??? ??? ??? private? int age = 0;
??? ??? ??? ??? private static class Inner{
??? ??? ??? ??? ??? public void show()
??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? System.out.println(age); //编译出错
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? }
??? 静态内部类里也可以直接访问外部类的静态成员,当在静态内部类访问某个静态属性时,
??? 优先级也是从内而外:内部类的静态成员变量>外部类的静态成员变量。
??? 因此,如果外部类的静态成员变量、内部类的静态成员变量同名,则可以通过使用
??? 外部类类名.变量名、内部类名.变量名作为限定来区分。
??? ??? 演示:
??? ??? ??? public class Outer {
??? ??? ??? ??? static String str = "这是外部类中的属性";
??? ??? ??? ??? private static class Inner
??? ??? ??? ??? {
??? ??? ??? ??? ??? private static String str = "这是内部类中的属性";
??? ??? ??? ??? ??? /**
??? ??? ??? ??? ??? ?* 打印外部类成员和内部类成员的方法
??? ??? ??? ??? ??? ?*/
??? ??? ??? ??? ??? public void showField()
??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? //System.out.println(age);
??? ??? ??? ??? ??? ??? ?String str = "这是局部变量";
??? ??? ??? ??? ??? ??? System.out.println("访问外部类成员:" + Outer.str);
??? ??? ??? ??? ??? ??? System.out.println("访问内部类成员:" + Inner.str);
??? ??? ??? ??? ??? ??? System.out.println("访问内部类方法中的局部变量:"
??? ??? ??? ??? ??? ??? ??? + str);
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? ??? /**
??? ??? ??? ??? ?* 创建访问内部类的方法
??? ??? ??? ??? ?*/
??? ??? ??? ??? public static void visitInnerClass()
??? ??? ??? ??? {
??? ??? ??? ??? ??? //创建内部类对象
??? ??? ??? ??? ??? Inner in = new Inner();
??? ??? ??? ??? ??? //调用打印方法
??? ??? ??? ??? ??? in.showField();
??? ??? ??? ??? }
??? ??? ??? ??? public static void main(String[] args) {
??? ??? ??? ??? ??? //创建外部类对象
??? ??? ??? ??? ??? Outer oc = new Outer();
??? ??? ??? ??? ??? oc.visitInnerClass();
??? ??? ??? ??? }
??? ??? ??? }
??? 在外部类以外使用静态内部类,内部类也不能用private修饰,语法如下:
??? ??? 外部类名.内部类名 标识符 = new 外部类名.内部类名();
??? ??? 演示:
??? ??? ??? public class Outer {
??? ??? ??? ??? public static class Inner
??? ??? ??? ??? {
??? ??? ??? ??? ??? public void show()
??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? System.out.println("这是内部类");
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? }
??? ??? ??? public class Test{
??? ??? ??? ??? public static void main(String[] args) {
??? ??? ??? ??? ??? Outer.Inner in = new Outer.Inner();
??? ??? ??? ??? ??? in.show();
??? ??? ??? ??? }
??? ??? ??? }
局部内部类:
??? 如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。
??? 因此局部内部类不能使用任何修饰符,如果需要使用局部内部类定义变量、创建实例或派生子类,
??? 那么都只能在局部内部类所在的方法内进行。
??? ??? 演示:
??? ??? ??? Public class Outer{
  ??? ??? ??? ??? public static void main(String[] args){
  ??? ??? ??? ??? ??? Class Inner{
  ??? ??? ??? ??? ??? ??? Int a;
??? ??? ??? ??? ??? }
  ??? ??? ??? ??? ??? Class InnerSub extends Inner{
  ??? ??? ??? ??? ??? ??? Int b;
  ??? ??? ??? ??? ??? }
  ??? ??? ??? ??? ??? Inner i = new InnerSub();
  ??? ??? ??? ??? ??? i.a = 8;
  ??? ??? ??? ??? }
  ??? ??? ??? }
??? 编译上面程序,生成了三个class文件:Outer.class、Outer$1Inner.class、Outer$1InnerSub.class。
??? 局部内部类的class文件比成员内部类的class文件多了一个数字,这是因为同一个类里不可能有两个
??? 同名的成员内部类,而同一个类里则可能有一个以上同名的局部内部类(处于不同的方法中),
??? 所以java为局部内部类的class文件名中增加了一个数字,作为区分。
匿名内部类:
??? 匿名内部类适合创建只需一次使用的类,定义匿名内部类的格式如下:
??? ??? new 父类构造器(实参列表) 或者 实现接口()
??? ??? {
??? ??? ??? //实体部分
??? ??? }
??? ???? 从定义格式可以看出,匿名内部类必须继承一个父类,或实现一个接口,有且继承或实现一个。
??? 关于内部类的两条规则:
??? ??? 1:匿名内部类不能是抽象类,因为在创建匿名内部类的同时,会立即创建匿名内部类的对象,
??? ??? ?? 因此不允许将匿名内部类定义成抽象类
??? ??? 2:匿名内部类不能定义构造器。因为匿名内部类没有类名。但可以定义实例初始化块。
??? 匿名内部类最常见的创建方式是定义在接口中,
??? ??? 演示:
??? ??? ??? public class FileTest {
??? ??? ???   ??? public static void main(String[] args) {
??? ??? ???   ??? ??? File file = new File("h:");
??? ??? ???   ??? ??? String[] strArr = file.list(new FilenameFilter()
??? ??? ???   ??? ??? {
??? ??? ???   ??? ??? ??? public boolean accept(File dir, String name) {
??? ??? ???   ??? ??? ??? ??? return new File(dir, name).isFile() &&
??? ??? ??? ??? ??? ??? ??? ??? name.endsWith(".java");
??? ??? ???   ??? ??? ??? }
??? ??? ???   ??? ??? });
??? ??? ???   ??? ??? for(String item : strArr)
??? ??? ???   ??? ??? {
??? ??? ???   ??? ??? ??? System.out.println(item);
??? ??? ???   ??? ??? }
??? ??? ???   ??? }
??? ??? ??? }
??? 注意事项:
??? ??? 当创建匿名内部类是,必须实现接口或抽象父类里的所有抽象方法。如果匿名内部类和
??? ??? 局部内部类里需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量。
??? ??? 演示:
??? ??? ??? public class OuterClass {
??? ??? ??? ??? public static void main(String[] args)
??? ??? ??? ??? {
??? ??? ??? ??? ??? final int a = 20;
??? ??? ??? ??? ??? class InnerClass
??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? public void show()
??? ??? ??? ??? ??? ??? {
??? ??? ??? ??? ??? ??? ??? //如果不加final,此处报错
??? ??? ??? ??? ??? ??? ??? System.out.println(a);
??? ??? ??? ??? ??? ??? }
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? }???

------- android培训、java培训、期待与您交流! ----------

读书人网 >编程

热点推荐