您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java 内部类详解

时间:2020-03-09 14:07:57  来源:  作者:

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("在接口中利用匿名内部类实现接口");
                 
             }
         };
     }
     
 }

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



Tags:Java 内部类   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
内部类内部定义普通类、抽象类、接口的统称,是指一种嵌套的结构关系。缺点:破坏了良好的程序结构。优点:内部类定义在类的内部,可以方便访问外部类的的私有成员,并且和其它类进...【详细内容】
2020-03-09  Tags: Java 内部类  点击:(39)  评论:(0)  加入收藏
1.为什么使用内部类?使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响1.1.使用内部类...【详细内容】
2019-09-09  Tags: Java 内部类  点击:(116)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条