Java 内部类

如果将一个类放在另一个类内部,那这个类就被称为内部类,内部类的主要作用如下:


1、内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。


2、内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相


访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。


3、匿名内部类适合用于创建那些仅需要一次使用的类。


成员内部类被分为两种:静态内部类和非静态内部类,使用static修饰的成员内部类是静态内部类,没有使用static


修饰的成员内部类就是非静态内部类。例如:


  1. public class Work {  
  2.       
  3.     public class Teacher{     
  4.     }  
  5.       
  6.     static class Student{     
  7.     }  
  8.   
Teacher类是非静态内部类,而Student类是静态内部类。


当在非静态内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在就使


用该变量;如果不存在,就到该方法所在的内部类中查找是否存在该名字的成员变量,如果存在就使用该成员变


量;如果不存在,就继续到内部类所在的外部类中查找是否存在该名字的成员变量,如果存在就使用该成员变量;


如果不存在,系统将出现编译错提示找不到该变量。因此,如果外部类成员变量、内部类成员变量与内部类里方法


的局部变量同名,可以通过使用this、外部类类名.this 作为限定来区分,例如:

  1. public class Work {  
  2.     String name="work";  
  3.       
  4.     public class Teacher{  
  5.         String name="Teacher";  
  6.         private void test(){  
  7.             String name="test";  
  8.             System.out.println("外部类的name:"+Work.this.name);  
  9.             System.out.println("内部类的成员name:"+this.name);  
  10.             System.out.println("内部类方法中局部变量name:"+name);  
  11.         }  
  12.     }  
  13.       
  14.     static class Student{     
  15.     }  
  16.     public static void main(String[] args) {  
  17.         Work.Teacher teacher=new Work().new Teacher();  
  18.         teacher.test();  
  19.           
  20.     }  
  21.   
输出结果:

外部类的name:work
内部类的成员name:Teacher
内部类方法中局部变量name:test

上面程序分别获取了外部类的实例变量、非静态内部类的实例变量。


如果使用static修饰一个内部类,那这个类就属于外部类本身,不属于外部类的某个对象,因此使用static修饰的内


部类被称为静态内部类。


静态内部类可以包含静态成员,也可以包含非静态成员。静态内部类不能访问外部类的实例成员,只能访问外部类


的类成员。静态内部类是外部类的一个静态成员,因此外部类的静态方法、静态初始化块中可以使用静态内部类来


定义变量、创建对象等。外部类依然不可以直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者


来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。


匿名内部类适合创建那种只需要一次使用的类,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承


一个父类或实现一个接口。匿名内部类的两条规则:


1、匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,因此不允许将匿名


内部类定义成抽象类。


2、匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初


始化块,通过实例初始化块来完成构造器需要完成的事情。


以下是最常用的匿名内部类用法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public interface Info {  
  2.     public String name();  
  3.     public int age();  
  4. }

  1. public class Teacher {  
  2.     public void test(Info info){  
  3.         System.out.println("name="+info.name()+"\nage="+info.age());  
  4.     }  
  5.     public static void main(String[] args) {  
  6.         Teacher teacher=new Teacher();  
  7.         teacher.test(new Info(){  
  8.               
  9.             @Override  
  10.             public String name() {  
  11.                 return "bill";  
  12.             }  
  13.               
  14.             @Override  
  15.             public int age() {  
  16.                 return 25;  
  17.             }  
  18.         });  //注意那个红括号
  19.     }  
  20. }  
输出结果:

name=bill
age=25



闭包(Closure)是一种能被调用的对象,它保存了创建它的作用域信息,对于静态内部类而言,它不仅记录其外部


类的详细信息,还保留了一个创建非静态内部类对象的引用,并且可以直接调用外部类的private成员,因此可以把


非静态内部类当成面向对象领域的闭包。通过这种仿闭包的非静态内部类,可以很方便的实现回调功能,回调就是


某个方法一旦获得了内部类对象的引用后,就可以再合适的时候反过来去调用外部类实例的方法。例如下程序:

  1. public interface Info {  
  2.     public void work();  

  1. public class Teacher {  
  2.     private String name;  
  3.     public Teacher(String name){  
  4.         this.name=name;  
  5.     }  
  6.     public void test(){  
  7.         System.out.println(name+"在工作");  
  8.     }  
  9.       
  10.     private class Work implements Info{  
  11.         @Override  
  12.         public void work() {  
  13.             test();  
  14.         }     
  15.     }  
  16.     public Info getWorkInfo(){  
  17.         return new Work();  
  18.     }  
  19.       
  20.       
  21.       
  22.     public static void main(String[] args) {  
  23.         Teacher teacher=new Teacher("Bill");  
  24.         teacher.getWorkInfo().work();  
  25.           
  26.     }  
输出结果:

Bill在工作


在上面程序,回调了Teacher对象的test方法,内部类可以很方便的回调其外部类的Field、方法,这样可以提高编程的灵活性。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值