内部类内容解析

内部类的区分

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

成员内部类

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

    注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。
  1. 代码例子
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();
}
}
  1. 作用

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

局部内部类

  • 定义在一个方法或者一个作用域里面的类。
  • 局部内部类中不可定义静态变量,可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的。
  1. 代码例子
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{ //专门用来给局部内部类做向上转型的父接口的操作 }

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

2. 作用

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

静态内部类

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

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

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

匿名内部类

  • 一个没有名字的类,是内部类的简化写法。
  • 本质:其实是继承该类或者实现接口的子类匿名对象。
  1. 代码例子
//代码示例一
public class Demo4 {
public Outinterface2 action() {
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();
} }

二、实现多继承

我们之前的学习知道,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中就间接的实现了多继承。

三、用匿名内部类实现回调功能

我们用通俗讲解就是说在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("具体实现接口")
}
}
}
}

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

编写一个接口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内部类的四种分类以及作用介绍的更多相关文章

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

     java内部类及四种内部类的实现方式 一.内部类定义:内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类. 二.为何要内部类?a.内部类提供了某种进入外围类的窗户.b.也是最吸引人的原因, ...

  2. JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例

    简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...

  3. Java中的四种引用

    引用定义 实际上,Java中存在四种引用,它们由强到弱依次是:强引用.软引用.弱引用.虚引用.下面我们简单介绍下这四种引用: 强引用(Strong Reference):通常我们通过new来创建一个新 ...

  4. JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)

    1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...

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

    转自http://blog.csdn.net/a1237871112/article/details/50926975 及http://blog.csdn.net/blackmanren/articl ...

  6. Java 1.ExecutorService四种线程池的例子与说明

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

  7. 下面给出了四种设计模式的作用: 外观(F

    下面给出了四种设计模式的作用: 外观(Fa?ade :为子系统中的一组功能调用提供一个一致的接口,这个接口使得这一子系统更加容易使用: 装饰(Decorate):当不能采用生成子类的方法进行扩充时,动 ...

  8. JAVA中的四种JSON解析方式详解

    JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...

  9. 【转帖】四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho

    四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho 1 BI系统的简述 从技术角度来说 BI 包含了 ETL.DW.OLAP.DM等多环节.简单的说就是把交易系统 ...

随机推荐

  1. ionic2踩坑之ionic resources失败

    网上关于ionic2怎么修改应用图标和启动画面资料也挺多的.不过大家执行ionic resources的时候不少人都执行失败了,关于执行失败的原因网上很少.下面分享一下我的经验吧. 1.看自己的项目下 ...

  2. C语言Windows程序设计—— 使用计时器

    传统意义上的计时器是指利用特定的原理来测量时间的装置, 在古代, 常用沙漏.点燃一炷香等方式进行粗略的计时, 在现代科技的带动下, 计时水平越来越高, 也越来越精确, 之所以需要进行计时是在很多情况下 ...

  3. jstl之核心标签

    JSP 标准标签库(JSTL) JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签, ...

  4. Nginx笔记总结四:Nginx连接PHP5.4

    location ~ .*\.(php)?${ expires -ls; try_file $uri=404; fastcgi_split_path_info ~(.+\.php)(/.+)$; in ...

  5. 转发: python3.7下 Flask-SQLAlchemy中解决1366报错

    原链接:https://segmentfault.com/a/1190000010596306 详情: 安装MySQL驱动(我升级过Python,所以要再装一遍) 本想安装MySQL官方驱动mysql ...

  6. hql错误:No data type for node: org.hibernate.hql.ast.tree.IdentNode

    今天写了一个查询,用的是hql,数据库是mysql.多表联查,结果报错了报: \-[IDENT] IdentNode: 'routerNumber' {originalText=routerNumbe ...

  7. MyBatis学习总结之一对多映射

    1.首先创建2张表:students 和grades create table grades( gid ) primary key, gname varchar() ); create table s ...

  8. c#数据库解析

    引言工作需要将数十万条文本数据解析存入Mysql数据库中,代码使用C#实现,存储效率还可以,以下是一些主要代码的说明. txtdataToMysql 项目描述:解析文本文件,该文件使用爬虫爬下的数十万 ...

  9. 修改 MyEclipse 编辑区域背景颜色

  10. Django学习之路05

    Django模板层 模板层语法(两类) 变量相关:{{      }} 逻辑相关:{%  %} 给模板传值的方法 #方法1 #通过字典传值,指名道姓,例如下 return render(request ...