内部类的作用

内部类,计算机面向对象程序设计概念。向对象程序设计中,可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型,即静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。内部类是JAVA语言的主要附加部分。内部类几乎可以处于一个类内部任何位置,可以与实例变量处于同一级,或处于方法之内,甚至是一个表达式的一部分。

 

一、 定义

放在一个类的内部的类我们就叫内部类。

二、 作用

1.内部类可以很好的实现隐藏

 一般的非内部类,是不允许有 private protected权限的,但内部类可以

2.内部类拥有外围类的所有元素的访问权限

3.可是实现多重继承

4.可以避免修改接口而实现同一个类中两种同名方法的调用。

 

三、   例子

1.实现隐藏

   平时我们对类的访问权限,都是通过类前面的访问修饰符来限制的,一般的非内部类,是不允许有 private protected权限的,但内部类可以,所以我们能通过内部类来隐藏我们的信息。可以看下面的例子

接口

  1. package insidecategory;  
  2.    
  3. public interface Incrementable  
  4. {  
  5.  void increment();  
  6. }  

 

  1. //具体类  
  2. package insidecategory;  
  3.    
  4. public class Example {  
  5.     
  6.     private class InsideClass implements InterfaceTest  
  7.     {  
  8.          public void test()  
  9.          {  
  10.              System.out.println("这是一个测试");  
  11.          }  
  12.     }  
  13.     public InterfaceTest getIn()  
  14.     {  
  15.         return new InsideClass();  
  16.     }  
  17. }  
  18. //上面加粗的部分是内部类,访问修饰符是private  


 

  1. //客户端程序   
  2. package insidecategory;  
  3.    
  4. public class TestExample {  
  5.    
  6.  public static void main(String args[])  
  7.  {  
  8.     Example a=new Example();  
  9.     InterfaceTest a1=a.getIn();  
  10.     a1.test();  
  11.  }  
  12. }  

 

加粗的那部分就是客户端调用的代码,从这段代码里面我只知道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.    }  
  22. }  


看上面加粗部分,name这个变量是在TagBean里面定义的私有变量。这个变量在内部类中可以无条件地访问System.out.println(name);

 

3.可以实现多重继承

    个特点非常重要,个人认为它是内部类存在的最大理由之一。正是由于他的存在使得Java的继承机制更加完善。大家都知道Java只能继承一个类,它的多重继承在我们没有学习内部类之前是用接口来实现的。但使用接口有时候有很多不方便的地方。比如我们实现一个接口就必须实现它里面的所有方法。而有了内部类就不一样了。它可以使我们的类继承多个具体类或抽象类。大家看下面的例子。

  1. //类一   
  2.  package insidecategory;  
  3.    
  4. public class Example1 {  
  5.    
  6.    public String name()  
  7.    {  
  8.        return "liutao";  
  9.    }  
  10. }  
  1. //类二   
  2. package insidecategory;  
  3.    
  4. public class Example2 {  
  5.    
  6.     public int age()  
  7.     {  
  8.         return 25;  
  9.     }  
  10. }  
  1.    
  2. //类三   
  3.  package insidecategory;  
  4.    
  5. public class MainExample  
  6. {  
  7.    private class test1 extends Example1  
  8.     {  
  9.         public String name()  
  10.         {  
  11.           return super.name();  
  12.         }  
  13.     }  
  14.     private class test2 extends Example2  
  15.     {  
  16.        public int age()  
  17.        {  
  18.          return super.age();  
  19.        }  
  20.     }  
  21.    public String name()  
  22.     {  
  23.     return new test1().name();  
  24.    }  
  25.    public int age()  
  26.    {  
  27.        return new test2().age();  
  28.    }  
  29.    public static void main(String args[])  
  30.    {  
  31.        MainExample mi=new MainExample();  
  32.        System.out.println("姓名:"+mi.name());  
  33.        System.out.println("年龄:"+mi.age());  
  34.    }  
  35. }  


 

大家注意看类三,里面分别实现了两个内部类 test1,test2 test1类又继承了Example1test2继承了Example2,这样我们的类三MainExample就拥有了Example1Example2的方法和属性,也就间接地实现了多继承。

四、 避免修改接口而实现同一个类中两种同名方法的调用。

 大家假想一下如果,你的类要继承一个类,还要实现一个接口,可是你发觉你继承的类和接口里面有两个同名的方法怎么办?你怎么区分它们??这就需要我们的内部类了。看下面的代码

  1. //接口   
  2.  package insidecategory;  
  3.    
  4. public interface Incrementable  
  5. {  
  6.  void increment();  
  7. }  
  1.    
  2. //类 MyIncrement   
  3.    package insidecategory;  
  4.    
  5. public class MyIncrement {  
  6.    
  7.     public void increment()  
  8.     {  
  9.       System.out.println("Other increment()");  
  10.     }  
  11.     static void f(MyIncrement f)  
  12.     {  
  13.         f.increment();  
  14.     }  
  15.    
  16. }  
  1. //大家看上面加黑的部分,两个方法都是一样的。在看下面这个类要继承这两个类   
  2. //如果不用内部类   
  3. package insidecategory;  
  4.    
  5. public class Callee2 extends MyIncrement implements Incrementable  
  6. {  
  7. public void increment()  
  8.       {  
  9.         //代码   
  10.        }  
  11. }  
  1. 想问一下大家increment()这个方法是属于覆盖MyIncrement这里的方法呢?还是Incrementable这里的方法。我怎么能调到MyIncrement这里的方法?显然这是不好区分的。而我们如果用内部类就很好解决这一问题了。看下面代码  
  1. package insidecategory;  
  2.    
  3. public class Callee2 extends MyIncrement  
  4. {  
  5.  private int i=0;  
  6.  private void incr()  
  7.  {  
  8.        i++;  
  9.        System.out.println(i);  
  10.  }  
  11.  private class Closure implements Incrementable  
  12.  {  
  13.       public void increment()  
  14.       {  
  15.         incr();  
  16.       }  
  17.  }  
  18.  Incrementable getCallbackReference()  
  19.  {  
  20.       return new Closure();  
  21.  }  
  22. }  

 

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

原文地址:https://www.cnblogs.com/gxpblogs/p/3068049.html