<返回更多

Java 内部类详解

2020-03-09    
加入收藏

Java 内部类详解

 

内部类

内部定义普通类、抽象类、接口的统称,是指一种嵌套的结构关系。

缺点:破坏了良好的程序结构。

优点:内部类定义在类的内部,可以方便访问外部类的的私有成员,并且和其它类进行隔离,每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

成员内部类-外部类访问内部类私有成员

成员内部类是依托外部类而存在的,定义在类内部的非静态类,就是成员内部类。代码示例如下:

 package neibu;
 class Outer{
     private int age ;
     private int name ;  
     public Outer() {
         super();
         // TODO Auto-generated constructor stub
     }
 
     public Outer(int age) {
         super();
         this.age = age;
     }
     
     public Intter getInfo() {
         Intter inter = new Intter("guoqun");
         return inter ;
         }
     
     class Intter{
         private String name ;
         
         
         public Intter(String name) {
             super();
             this.name = name;
         }
 
         public void name() {
              /*Intter类 像是Outer类的一个成员,Outer称为外部类。
              成员内部类可以无条件访问外部类的所有成员属性和成员方法,
              包括private成员和静态成员。*/
             System.out.println(Outer.this.age + this.name);
             
         }
     }
 }

Intter类是Outer类的一个内部类,Outer称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法,包括private成员和静态成员。

需要注意的是,虽然成员内部类可以无限制的访问外部类中成员或方法,但当成员内部类与外部类拥有同名成员变量或者方法时,会发生覆盖,即默认情况下访问的是成员内部类的成员,如上述代码示例的name成员变量。如果要访问外部类的同名成员,需要以下面的形式进行访问:

 外部类.this.成员变量 ,如Outer.this.age
 外部类.this.成员方法

外部类访问成员内部类的成员,需要先创建一个成员内部类的对象,再通过引用来访问内部类成员。

内部类可以直接被实例化,语法格式:

 外部类.内部类 对象名称 = new 外部类().new 内部类();

代码示例如下:

 public class Lian {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         Outer.Intter inttera = new Outer(10).new Intter("guoqun");
         inttera.name();
     }
 }

内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。内部类私有化,可以使用 private、protected实现。如上面示例中,如果成员内部类Intter使用private进行修饰,那么只能在外部类的内部访问;如果用protected进行修饰,那么只能在同一个包下或继承外部类时访问;如果使用public进行修饰,那么在任何地方都能访问;如果是默认访问权限(default),则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public或default访问权限修饰。

 

定义内部接口

 package neibu;
 
 interface Jiekou<T>{
     
     public abstract void jie(T x);
     // 内部接口
     interface KouJie {
         public abstract void fun();
 
     }
 
 ​
 class Jj<T> implements Jiekou<T>{
     public void jie(T x) {
         System.out.print(x);
     }
     
     class Abs implements KouJie {
         public  void fun() {
             System.out.print("asdasda");
 ​
         }
     }
     
 }

实例化内部类接口实例化对象前需要首先获取外部类实例化对象,代码示例如下:

 public class Lian {
 
     public static void main(String[] args) {
         // 实例化外部类接口对象
         neibu.Jiekou<Integer> Jie = new neibu.Jj<Integer> () ;
         Jie.jie(10 );
         // 实例化内部类接口实例化对象前需要首先获取外部类实例化对象
         Jiekou.KouJie kou = ((Jj) Jie).new Abs();
         kou.fun();
     }
 ​
 }

 

接口子类定义为自身内部类

 package neibu;
 public class Lian {
 
     public static void main(String[] args) {
     
         FaceM.getFace().getInfo();
     }
     
 }
 interface FaceM{
     public abstract void getInfo();
     class mm implements FaceM {
         public void getInfo() {
             System.out.println("接口子类定义为自身内部类");
         }
     }
     public static FaceM getFace() {
         return new mm(); 
     }
 }

 

static 定义内部类(静态内部类)

使用static定义内部类,此时的内部类不再受外部类实例化对象的影响,所以等同于于一个“外部类”,内部类的名称为“外部类.内部类”,同时static定义的内部类只能调用外部类中static定义的结构,并且在进行内部类的实例化时也不再需要先获取外部类实例化对象,static内部类对象实例化格式如下:

外部类内部类内部类对象外部类内部类

 package neibu;
 public class Lian {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         System.out.println();
         Outer.Intter inttera = new Outer.Intter("guoqun");
         inttera.name();
         }
 }
 class Outer{
     public Outer(int age) {
         super();
         this.age = age;
     }
     
     public Intter getInfo() {
         Intter inter = new Intter("guoqun");
         return inter ;
         }
     
     private int age ;   
     static class Intter{
         private String name ;   
         public Intter(String name) {
             super();
             this.name = name;
         }
 
         public void name() {
             System.out.println(this.name);
             
         }
     }
 }

使用static 定义内部接口(静态内部类)

 package neibu;
 public class Lian {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         System.out.println();
         JieKou.Load load = new LoadFace();
         JieKou.Compare compare = new CompareFace();
         JieKou.getInfo(load, compare);
     }
 
 }
 
 interface JieKou{
     // 内部接口
     static interface Load {
         public abstract boolean loadData(); 
     }
     
     static interface Compare {
         public abstract void compareData(); 
     }
     
     public static void getInfo(Load sLoad , Compare sCompare) {     
         if (sLoad.loadData()) {
             Compare.compareData();  
         }
         else {
             System.out.println("加载失败");
         }
     }
 }
 
 class LoadFace implements JieKou.Load{
     public boolean loadData() {
         return true;
     }
 }
 
 class CompareFace implements JieKou.Compare{
     public void  compareData() {
         System.out.println("compareData");      
     }
 }
 

方法中定义内部类(局部类)

 package neibu;
 
 public class Lian {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         System.out.println();
         Outer outer = new Outer(12);
         outer.getInfo();
     }
 
 }
 
 
 class Outer{
     private int  age ;
     public Outer(int age ) {
         this.age = age ;
     }
     public void   getInfo() {
         class Inter {  // 内部类 
             public void interFun() {
                 System.out.println("interFun" + Outer.this.age) ;   
             }
         }
          new Inter().interFun() ;
         
     }
 }

如果一个类只在某个方法中使用,则可以考虑使用局部类。

匿名内部类,函数式接口

匿名内部类使用广泛,如我们常用的绑定监听的时候。

 package neibu;
 public class Lian {
     public static void main(String[] args) {
         /*
         接口对象无法直接实例化,使用匿名内部类后就可以利用对象的实例化格式获取接口实例
         */
         Face face  = new Face() { // 匿名内部类  
             @Override
             public void name() {
                 // TODO Auto-generated method stub
                 System.out.println("sss");
             }
         };
     }
 
 }
 
 @FunctionalInterface
 interface Face {
     public abstract void name();
     
 }

在接口中利用匿名内部类实现接口

 package neibu;
 public class Lian {
     public static void main(String[] args) {
         FaceN.getFace().name();
     }
 
 }
 interface FaceN {
     public abstract void name();
     public static FaceN getFace() {
         return new FaceN() {    
             @Override
             public void name() {
                 System.out.println("在接口中利用匿名内部类实现接口");
                 
             }
         };
     }
     
 }

适合于接口只有一个子类的时候,并且也可以对外部调用处隐含子类。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>