博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内部类的作用
阅读量:6294 次
发布时间:2019-06-22

本文共 4804 字,大约阅读时间需要 16 分钟。

来一个最基本的简单例子:
 
 
  1. package com.hanchao.test; 
  2. /** 
  3.  * 内部类 
  4.  * @author hanlw 
  5.  * 2012-07-12 
  6.  */ 
  7. public class MyClass { 
  8.  
  9.     private int age; 
  10.     private int age2; 
  11.      
  12.     //注意:一个Java文件中可以存放n个类,但是只能有一个public类!! 
  13.      
  14.     /** 
  15.      * MyClass类的内部类1 
  16.      * @author Administrator 
  17.      * 
  18.      */ 
  19.     public class MyClass2{ 
  20.         private int age; 
  21.          
  22.         //内部类的方法 
  23.         public void say() { 
  24.             /** 
  25.              * 调用外部类的属性的方法:外部类名.this.属性名  
  26.              *  
  27.              * 注意:在内部类中可以调用外部类的属性和方法, 
  28.              * 但是在外部类中不能调用内部类的属性和方法 
  29.              *  
  30.              * 给外部类的age2赋值=25 
  31.              */ 
  32.             MyClass.this.age2 = 25
  33.             MyClass.this.age = 19
  34.              
  35.             //给内部类的age赋值为20 
  36.             this.age = 20
  37.              
  38.             System.out.println("--内部类--"); 
  39.             System.out.println(age); 
  40.             System.out.println("--外部类--"); 
  41.             System.out.println(age2);//可以直接调用age2.因为内部类没有和age2同名的属性 
  42.             System.out.println(MyClass.this.age); 
  43.              
  44.         } 
  45.     } 
  46.      
  47.     /** 
  48.      * MyClass的内部类2-----实现接口的内部类 
  49.      * @author hanlw 
  50.      * 2012-07-12 
  51.      */ 
  52.     public class MyThread implements Runnable { 
  53.  
  54.         public void run() { 
  55.             System.out.println("这是一个实现了接口的内部类。。。。。。"); 
  56.         } 
  57.     } 
  58.      
  59.      
  60.     /** 
  61.      * 3.匿名内部类的使用,eg 
  62.      */ 
  63.     Thread t = new Thread(new Runnable() { 
  64.         public void run() { 
  65.             System.out.println("匿名的内部类!!"); 
  66.         } 
  67.     }); 
  68.      
  69.     public void hello() { 
  70.          
  71.         t.start(); 
  72.     } 
  73.  
  74.      
  75.     //----------------------------------------------------- 
下面是测试的main方法:
 
 
  1. package com.hanchao.test; 
  2. /** 
  3.  *  
  4.  * @author hanlw 
  5.  * 2012-07-14 
  6.  */ 
  7. public class Test { 
  8.  
  9.     public static void main(String[] args) { 
  10.          
  11.         /** 
  12.          * 1.调用内部类的方法:挺神奇,好玩的哦!! 
  13.          *  
  14.          */ 
  15.         MyClass.MyClass2 my2 = new MyClass().new MyClass2(); 
  16.         my2.say(); 
  17.          
  18.         /** 
  19.          * 2.实现接口的内部类的测试 
  20.          */ 
  21.         MyClass.MyThread mt = new MyClass().new MyThread(); 
  22.         Thread t = new Thread(mt); 
  23.         t.start(); 
  24.          
  25.         /** 
  26.          * 3.匿名内部类的测试 
  27.          */ 
  28.         MyClass m = new MyClass(); 
  29.         m.hello(); 
  30.          
  31.     } 
 
一、 定义:放在一个类的内部的类我们就叫内部类。
 
二、 作用:
 
1.内部类可以很好的实现隐藏
 
  一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
 
2.内部类拥有外围类的所有元素的访问权限
 
3.可是实现多重继承
 
4.可以避免修改接口而实现同一个类中两种同名方法的调用。
 
三、   例子
 
1.实现隐藏
 
   平时我们对类的访问权限,都是通过类前面的访问修饰符来限制的,一般的非内部类,是不允许有 private 与protected权限的,但内部类可以,所以我们能通过内部类来隐藏我们的信息。可以看下面的例子
 
接口
 
 
  1. package insidecategory; 
  2.  
  3. public interface Incrementable 
  4.   void increment(); 
具体类
 
 
  1. package insidecategory; 
  2.  
  3. public class Example { 
  4.     
  5.     private class InsideClass implements InterfaceTest 
  6.     { 
  7.          public void test() 
  8.          { 
  9.              System.out.println("这是一个测试"); 
  10.          } 
  11.     } 
  12.     public InterfaceTest getIn() 
  13.     { 
  14.         return new InsideClass(); 
  15.     } 
上面红色的部分是内部类,访问修饰符是private
 
客户端程序
 
 
  1. package insidecategory; 
  2.  
  3. public class TestExample { 
  4.  
  5.   public static void main(String args[]) 
  6.   { 
  7.     Example a=new Example(); 
  8.     InterfaceTest a1=a.getIn(); 
  9.     a1.test(); 
  10.   } 
红色的那部分就是客户端调用的代码,从这段代码里面我只知道Example的
getIn()方法能返回一个InterfaceTest 实例但我并不知道这个实例是这么实现的。而且由于InsideClass 是private的,所以我们如果不看代码的话根本看不到这个具体类的名字,所以说它可以很好的实现隐藏。
2.可以无条件地访问外围类的所有元素
 
 
  1. package insidecategory; 
  2.  
  3. public class TagBean { 
  4.  
  5.  private String name="liutao"
  6.    private class InTest 
  7.    { 
  8.       public InTest() 
  9.       { 
  10.           System.out.println(name); 
  11.       } 
  12.    } 
  13.    public void test() 
  14.    { 
  15.     new InTest(); 
  16.    } 
  17.    public static void main(String args[]) 
  18.    { 
  19.        TagBean bb=new TagBean(); 
  20.        bb.test(); 
  21.    } 
看上面红色部分,name这个变量是在TagBean里面定义的私有变量。这个变量在内部类中可以无条件地访问System.out.println(name);
 
 3.可以实现多重继承
 
     非常重要,个人认为它是内部类存在的最大理由之一。正是由于他的存在使得Java的继承机制更加完善。大家都知道Java只能继承一个类,它的多重继承在我们没有学习内部类之前是用接口来实现的。但使用接口有时候有很多不方便的地方。比如我们实现一个接口就必须实现它里面的所有方法。而有了内部类就不一样了。它可以使我们的类继承多个具体类或抽象类。大家看下面的例子。
 
类一
 
 
  1.   package insidecategory; 
  2.  
  3. public class Example1 { 
  4.  
  5.    public String name() 
  6.    { 
  7.        return "liutao"
  8.    } 
 
类二
 
 
  1. package insidecategory; 
  2.  
  3. public class Example2 { 
  4.  
  5.     public int age() 
  6.     { 
  7.         return 25
  8.     } 
 
类三
 
 
  1.  package insidecategory; 
  2.  
  3. public class MainExample  
  4.    private class test1 extends Example1  
  5.     { 
  6.         public String name() 
  7.         { 
  8.           return super.name(); 
  9.         } 
  10.     } 
  11.     private class test2 extends Example2 
  12.     { 
  13.        public int age() 
  14.        { 
  15.          return super.age(); 
  16.        } 
  17.     } 
  18.    public String name() 
  19.     { 
  20.     return new test1().name();  
  21.    } 
  22.    public int age() 
  23.    { 
  24.        return new test2().age(); 
  25.    } 
  26.    public static void main(String args[]) 
  27.    { 
  28.        MainExample mi=new MainExample(); 
  29.        System.out.println("姓名:"+mi.name()); 
  30.        System.out.println("年龄:"+mi.age()); 
  31.    } 
大家注意看类三,里面分别实现了两个内部类 test1,和test2 ,test1类又继承了Example1,test2继承了Example2,这样我们的类三MainExample就拥有了Example1和Example2的方法和属性,也就间接地实现了多继承。
四、 避免修改接口而实现同一个类中两种同名方法的调用。
 
  大家假想一下如果,你的类要继承一个类,还要实现一个接口,可是你发觉你继承的类和接口里面有两个同名的方法怎么办?你怎么区分它们??这就需要我们的内部类了。看下面的代码
 
 
  1. 接口 
  2.  package insidecategory; 
  3.  
  4. public interface Incrementable 
  5.   void increment(); 
  6.  
  7. 类  MyIncrement 
  8.    package insidecategory; 
  9.  
  10. public class MyIncrement { 
  11.  
  12.     public void increment() 
  13.     { 
  14.       System.out.println("Other increment()"); 
  15.     } 
  16.     static void f(MyIncrement f) 
  17.     { 
  18.         f.increment(); 
  19.     } 
  20.  
大家看上面红色的部分,两个方法都是一样的。在看下面这个类要继承这两个类
如果不用内部类
package insidecategory;
public class Callee2 extends MyIncrement implements Incrementable
{
public void increment()
      {
        //代码
       }
}
 
想问一下大家increment()这个方法是属于覆盖MyIncrement这里的方法呢?还是Incrementable这里的方法。我怎么能调到MyIncrement这里的方法?显然这是不好区分的。而我们如果用内部类就很好解决这一问题了。看下面代码
 
 
  1. package insidecategory; 
  2.  
  3. public class Callee2 extends MyIncrement 
  4.   private int i=0
  5.   private void incr() 
  6.   { 
  7.        i++; 
  8.        System.out.println(i); 
  9.   } 
  10.   private class Closure implements Incrementable 
  11.   { 
  12.       public void increment() 
  13.       { 
  14.         incr(); 
  15.       } 
  16.   } 
  17.   Incrementable getCallbackReference() 
  18.   { 
  19.       return new Closure(); 
  20.   } 

我们可以用内部类来实现接口,这样就不会与外围类的方法冲突了。一、 

四.更多了解请参考这篇博客:

 

 

 

 

 

 

 

定义
一个类的内部的类我们就叫内部类。

     本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/930721,如需转载请自行联系原作者

你可能感兴趣的文章
@RequestMapping 用法详解之地址映射
查看>>
254页PPT!这是一份写给NLP研究者的编程指南
查看>>
《Data Warehouse in Action》
查看>>
String 源码浅析(一)
查看>>
Spring Boot 最佳实践(三)模板引擎FreeMarker集成
查看>>
Fescar 发布 0.2.3 版本,支持 Redis 和 Apollo
查看>>
Google MapReduce到底解决什么问题?
查看>>
CCNP-6 OSPF试验2(BSCI)
查看>>
Excel 2013 全新的图表体验
查看>>
openstack 制作大于2TB根分区自动扩容的CENTOS镜像
查看>>
Unbuntu安装遭遇 vmware上的Easy install模式
查看>>
几个常用的ASP木马
查看>>
python分析postfix邮件日志的状态
查看>>
Mysql-5.6.x多实例配置
查看>>
psutil
查看>>
在git@osc上托管自己的代码
查看>>
机器学习算法:朴素贝叶斯
查看>>
小五思科技术学习笔记之扩展访问列表
查看>>
使用Python脚本检验文件系统数据完整性
查看>>
使用MDT部署Windows Server 2003 R2
查看>>