本文转载自:Java内部类的四种分类以及作用


一、内部类内容解析

1. 内部类的区分

内部类分别有成员内部类、局部内部类、匿名内部类、静态内部类,接下来将分别介绍。

2. 成员内部类

  • 就是位于外部类成员位置的类。与外部类的属性、方法并列。
  • 成员内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为private,但是对于处于其内部的内部类还是可见的。)
  • 用成员内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。

注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。

①. 代码例子

public class Demo1 {innerclass in=new innerclass();//在成员内部类所在的外类中实例化成员内部类public void outf() {in.inf();//因为in是成员内部类的实例化,所以才可以调用}class innerclass{//成员内部类int y=0;public innerclass() {//成员内部类的构造方法}public void inf() {System.out.println("内部类方法y="+y);}}public static void main(String[] args) {Demo1 iDemo1=new Demo1();iDemo1.outf();Demo1.innerclass j= iDemo1.new innerclass();//非外部类位置成员内部类实例化的方法(即首先要实例化一个外部类)Demo1.innerclass k=new Demo1().new innerclass();//实例化外部类和构造内部类一起写j.inf();}
}

②. 作用

数据安全。如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的途径来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方法中增加一些判断语句,起到数据安全的作用。

3. 局部内部类

  • 定义在一个方法或者一个作用域里面的类。
  • 局部内部类中不可定义静态变量,可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的。

①. 代码例子

public class Demo2 {public outinterface action(String x) {//要把这个类返回出去,就需要通过接口,因为内部类在外部作用域中不存在class innerclass2 implements outinterface{public innerclass2(String s) {s = x;System.out.println(s);}}return new innerclass2("do");}public static void main(String[] args) {Demo2 demo2=new Demo2();demo2.action("局部内部类");}
}
interface outinterface{//专门用来给局部内部类做向上转型的父接口的操作
}

局部内部类只能在所在的方法体作用域内进行实例化,而如果要在所在方法体返回该类,就要通过接口向上转型的操作。(如同上处代码)

②. 作用

在某些情况下,某些业务逻辑需要临时处理,这些业务逻辑只在这里使用又可以封装成一个类的话,而又没必要重新建个文件,所以可以这写一个局部内部类来处理。然后,在我的记忆中,java代理模式中有用到局部内部类,在方法中直接实现接口,返回代理对象,简单而又方便。

4. 静态内部类

静态字段的内部类,和静态方法并列。

①. 代码例子

public class Demo3 {static int x=100;static class innerclass3 {void action() {x=1;//x必须是静态字段}public static void main(String[] args) {System.out.println("我是静态内部类");}}
}

②. 作用

提供调试作用。我将main方法写在静态内部类中,生成.class文件后,调试代码在静态内部类当中,当我删除静态内部类后,其他人仍然可以使用我的外部类。

5. 匿名内部类

  • 一个没有名字的类,是内部类的简化写法。
  • 本质:其实是继承该类或者实现接口的子类匿名对象。

①. 代码例子

//代码示例一
public class Demo4 {public Outinterface2 action() {//return new innerclass2(); ①return new Outinterface2() {//②private int i = 0;public int getvalue() {return i;}};}
}
interface Outinterface2 {
}
class innerclass2 implements Outinterface2{//①private int i = 0;public int getvalue() {return i;}
}
//代码示例二
interface Inner {public abstract void show();
}
​class Outer {public void method(){new Inner() {public void show() {System.out.println("HelloWorld");}}.show();}
}
​class Test {public static void main(String[] args)  {Outer o = new Outer();o.method();}
}
//如果匿名内部类中有多个方法又该如何调用呢?
Inter i = new Inner() {//多态,因为new Inner(){}代表的是接口的子类对象public void show() {System.out.println("HelloWorld");}
}

上述代码①和②的作用是相同的。由此也可以解释一下匿名内部类的作用。

②. 作用

我们在开发的时候,会看到抽象类,或者接口作为参数。而这个时候,实际需要的是一个子类对象。如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。

二、为什么使用内部类

1. 封装性

作为一个类的编写者,我们很显然需要对这个类的使用访问者的访问权限做出一定的限制,我们需要将一些我们不愿意让别人看到的操作隐藏起来,如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。

public interface Demo {void show();
}
class Outer {private class test implements Demo {public void show() {System.out.println("密码备份文件");}}public Demo getInner() {return new test();}
}

2. 实现多继承

我们之前的学习知道,java是不可以实现多继承的,一次只能继承一个类,我们学习接口的时候,有提到可以用接口来实现多继承的效果,即一个接口有多个实现,但是这里也是有一点弊端的,那就是,一旦实现一个接口就必须实现里面的所有方法,有时候就会出现一些累赘,但是使用内部类可以很好的解决这些问题。

public class Demo1 {public String name() {return "BWH_Steven";}
}
public class Demo2 {public String email() {return "xxx.@163.com";}
}
public class MyDemo {private class test1 extends Demo1 {public String name() {return super.name();}}​private class test2 extends Demo2  {public String email() {return super.email();}}​public String name() {return new test1().name();}​public String email() {return new test2().email();}​public static void main(String args[]) {MyDemo md = new MyDemo();System.out.println("我的姓名:" + md.name());System.out.println("我的邮箱:" + md.email());}
}

我们编写了两个待继承的类Demo1和Demo2,在MyDemo类中书写了两个内部类,test1和test2两者分别继承了Demo1和Demo2类,这样MyDemo中就间接的实现了多继承。

3. 用匿名内部类实现回调功能

我们用通俗讲解就是说在Java中,通常就是编写一个接口,然后你来实现这个接口,然后把这个接口的一个对象作以参数的形式传到另一个程序方法中, 然后通过接口调用你的方法,匿名内部类就可以很好的展现了这一种回调功能。

public interface Demo {void demoMethod();
}
public class MyDemo{public test(Demo demo){System.out.println("test method");}public static void main(String[] args) {MyDemo md = new MyDemo();//这里我们使用匿名内部类的方式将接口对象作为参数传递到test方法中去了md.test(new Demo){public void demoMethod(){System.out.println("具体实现接口")}}}
}

4. 解决继承及实现接口出现同名方法的问题

编写一个接口Demo

public interface Demo {void test();
}

编写一个类 MyDemo

public class MyDemo {​public void test() {System.out.println("父类的test方法");}
}

两者的方法名字都是test,下面编写一个测试类;

public class DemoTest extends MyDemo implements Demo {public void test() {}
}

这样的话我就有点懵了,这样如何区分这个方法是接口的还是继承的,所以我们使用内部类解决这个问题

public class DemoTest extends MyDemo {​​private class inner implements Demo {public void test() {System.out.println("接口的test方法");}}public Demo getIn() {return new inner();}public static void main(String[] args) {//调用接口而来的test()方法DemoTest dt = new DemoTest();Demo d = dt.getIn();d.test();//调用继承而来的test()方法dt.test();}
}
​//运行结果接口的test方法父类的test方法

本文转载自:Java内部类的四种分类以及作用

Java内部类的四种分类以及作用相关推荐

  1. Java 内部类的四种实现方式

    Java 内部类的四种实现方式 前言 今天的话我将为大家介绍Java的四种内部类,他们分别是普通内部类,静态内部类,局部内部类,匿名内部类. 提示:以下是本篇文章正文内容,下面案例可供参考 一.内部类 ...

  2. 内部类(四种内部类详解)

    == = = = = = = 内部类(四种内部类详解)= = = = = = = == 一.基本介绍:一个类的内部又完整的嵌套了另一个类结构.被嵌套的类称为内部类(inner class),嵌套其他类 ...

  3. 独家 | 机器学习中的四种分类任务(附代码)

    作者:Jason Brownlee 翻译:陈丹 校对:杨毅远 全文约4400字,建议阅读18分钟 本文为大家介绍了机器学习中常见的四种分类任务.分别是二分类.多类别分类.多标签分类.不平衡分类,并提供 ...

  4. Java 中的四种引用

    垃圾收集器与内存分配策略参考目录: 1.判断Java 对象实例是否死亡 2. Java 中的四种引用 3.垃圾收集算法 4. Java9中的GC 调优 5.内存分配与回收策略 在进行垃圾回收之前,虚拟 ...

  5. Java并发的四种风味:Thread、Executor、ForkJoin和Actor

    原文地址:Java并发的四种风味:Thread.Executor.ForkJoin和Actor 这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好的几种解决方法,Exe ...

  6. java中的四种代码块

    原文链接: java中的四种代码块_Munt的博客-CSDN博客_java中代码块 在java中用{}括起来的称为代码块,代码块可分为以下四种: 一.简介 1.普通代码块: 类中方法的方法体 2.构造 ...

  7. java的友好成员,java面向对象中四种权限(private,protected,public,友好型)详解...

    俗话说没有规矩就没有方圆,java作为一门严谨的面向对象的高级编程语言,自然对权限整个重要的问题有严格的控制. Java一共有四种权限,private (私有),public(公有).Protecte ...

  8. java 代码块_详解java中的四种代码块

    在java中用{}括起来的称为代码块,代码块可分为以下四种: 一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. ...

  9. 推荐 :机器学习中的四种分类任务(附代码)

    作者:Jason Brownlee  翻译:陈丹  校对:杨毅远 全文约4400字,建议阅读18分钟 本文为大家介绍了机器学习中常见的四种分类任务.分别是二分类.多类别分类.多标签分类.不平衡分类,并 ...

最新文章

  1. 壕!甲骨文创始人 8000 万美元买豪宅后打算拆掉
  2. [vue] 你有使用过vue开发多语言项目吗?说说你的做法?
  3. 在家怎么看公司服务器上的文件,怎么查看云服务器上的文件
  4. python远程备份mysql_python3把服务器备份mysql数据库下载到本地
  5. 程序员最想得到的十大证件
  6. 用DirectX Audio和DirectShow播放声音和音乐(3)
  7. shell中的文本处理(grep、sed、awk命令)
  8. AJAX 跨域调用和 Java 跨域 发送请求
  9. C++ Primer Plus 第三章编程练习
  10. java集合之Stack栈基础
  11. 智能语音概念界定及技术架构
  12. zkLedger: Privacy-Preserving Auditing for Distributed Ledgers zkLedger:保护分布式分类帐的隐私审计
  13. 宝塔搭建网站教程php,怎么利用宝塔面板搭建网站详细教程
  14. 奥德赛商务车改装哪一些是必要的?
  15. Windows Workflow Foundation(1)- Windows Workflow Foundation 概述
  16. QGis 使用高德 画KML
  17. js base64编码格式图片另存为下载
  18. html5交互式地铁线路图,HTML5 SVG城市地铁路线图动画演示
  19. 去看李记者,天津印象
  20. IPGuard三步打造桌面标准化

热门文章

  1. 架设个人Web服务器实战(通过ADSL路由)
  2. HDOJ HDU 1129 Do the Untwist
  3. mysql 1046_mysql 1046错误解决实例
  4. 02 Ajax表单提交
  5. 百度OCR识别图片文字,解决image format error错误
  6. Gateway服务网关使用教程
  7. 华为 2017 实习生招聘笔试题
  8. c++中二维数组与二维向量的长度
  9. Bubble(17)
  10. 文件下载(解决中文文件名下载乱码问题)(二)