1.什么是内部类?

定义在类内部的类,称之为内部类

public class Out{

class In{ //此时In就是内部类

}

}

2.为什么要使用内部类?

1),增强封装,把内部类隐藏在外部类中,不允许其他类来访问内部类

2),内部类能提高代码的可读性和可维护性

3.内部类的分类

对于内部类的分类,可以对比于成员变量的分类.

我们可以根据不同的修饰符或者定义的不同位置把成员变量,可以细分为:类成员变量,实例成员变量,局部变量.

内部类看做是外部类的一个成员,那么内部类可以使用public/缺省/protected/private修饰.还可以是static修饰.

同理,内部类也根据使用不同的修饰符或者定义的不同位置,将其分成4类:

1),实例内部类:内部类没有使用static修饰

2),静态内部类:内部类使用static修饰

3),局部内部类:在方法中定义的内部类

4),匿名内部类:只能使用一次,属于内部类的一种特殊情况

3.1实例内部类:

1)定义:实例内部类,即没有使用static修饰的内部类.这说明,实例内部类属于外部类的对象,不属于外部类本身(类比字段).

2)创建实例内部类

//外部类

class Outter {

// 实例内部类:没有使用static修饰

class Inner {

}

}

public class InnerDemo1 {

public static void main(String[] args) {

// 创建实例内部类,没有使用static修饰,属于外部类的对象,因此,创建实例内部类前,必须存在外部类对象

Outter out = new Outter();

// 通过外部类对象创建内部类对象

Outter.Inner in = out.new Inner();

}

}

3)特点:

a.由创建实例内部类的过程可知,当存在内部类对象时,一定存在外部类对象.

b.实例内部类的实例自动持有外部类的实例的引用,实例内部类可以无条件访问外部类的所有字段和方法

注意:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象

c.外部类中不能直接访问内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问

//外部类

class Outter {

private String name = "out";

private Integer age = 17;

// 实例内部类:没有使用static修饰

class Inner {

private Integer age = 18; // 隐藏现象,隐藏了外部类的age

Inner() {

// 特点:1.实例内部类能直接访问外部类成员

// 2.当实例内部类和外部类有同名的字段或者方法时,会发生隐藏现象

System.out.println(name + this.age);// 输出out18

// 此时若需要使用外部类的age,语法:外部类.this.age

System.out.println(Outter.this.age);// 输出17

}

}

}

总结:简单来说,就是看变量的作用域,外部类成员变量的作用域是整个外部类,而内部类在外部类中(可以看做外部类的字段),内部类自然就可以访问外部类.而外部类要去访问内部类的成员,可以这样理解:内部类的成员属于内部类,在内部类中有效,内部类都不存在,其中的成员变量也不会存在,所以,外部类中不能直接访问内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问.

3.2静态内部类

1)定义:使用static修饰的内部类.所以,该内部类属于外部类本身,而不属于外部类的对象

2)创建静态内部类

//外部类

class Outter {

// 静态内部类:使用static修饰

static class Inner {

}

}

public class InnerDemo2 {

public static void main(String[] args) {

// 因为静态内部类属于外部类本身,可以直接通过外部类类名来访问(类比字段)

Outter.Inner in = new Outter.Inner();

}

}

3)特点:

a.在创建内部类的实例时,不必创建外部类的实例.

b.静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问.

简单理解:静态成员属于类,非静态成员属于对象,如果要访问外部类的实例成员(非静态成员),当然要先存着外部类对象的.而静态内部类的创建是不需要外部类的对象,因此,如果访问外部类的实例成员,必须通过外部类的实例去访问.

c.在静态内部类中可以定义静态成员和实例成员.

d.测试类可以通过完整的类名直接访问静态内部类的静态成员.

//外部类

class Outter {

static String name = "outter";

public Integer age = 17;

// 静态内部类:使用static修饰

static class Inner {

Inner() {

// 静态内部类能直接访问外部类的静态成员

System.out.println(name);// 输出 outter

// 访问外部类的实例成员,必须通过外部类的实例去访问.

System.out.println(new Outter().age);// 输出 17

}

}

}

3.3局部内部类(几乎用不到)

1)定义:在方法中定义的内部类,其可见范围是当前方法,和局部变量是同一个级别,所以局部内部类只能在方法中使用.

注意,局部内部类和方法里面的局部变量一样,是不能有public、protected、private以及static修饰符的。

public class InnerDemo3 {

public static void main(String[] args) {

// 局部内部类

class Inner {

}

}

}

2)特点:

a.局部内部类和实例内部类一样,不能包含静态成员.(局部内部类属于方法,而静态成员属于类)

b.局部内部类和实例内部类,可以访问外部类的所有成员.

c.局部内部类访问的局部变量必须使用final修饰,在Java8中是自动隐式加上final(语法糖).

原因:当方法被调用运行完毕之后,当前方法的栈帧被销毁,方法内部的局部变量的空间全部销毁.但内部类对象可能还在堆内存中,要直到没有被引用时才会消亡.此时就会出现一种情况:内部类要访问一个不存在的局部变量.为了避免该问题,我们使用final修饰局部变量,从而变成常量,永驻内存空间,即使方法销毁之后,该局部变量也在内存中,对象可以继续持有.

public class InnerDemo3 {

public static void main(String[] args) {

int age = 17;

final int num = 15;

// 局部内部类

class Inner {

public void test() {

// 报错:Cannot refer to a non-final variable age inside an inner class defined in a different method

System.out.println(age);

System.out.println(num);// 正确

}

}

}

}

3.4匿名内部类(使用最频繁)

1):定义:匿名内部类是一个没有名称的局部内部类,适合于只使用一次的类.

2)创建匿名内部类:

匿名内部类本身没有构造器,但是会调用父类构造器.一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写.

注意:匿名内部类必须继承一个父类或者实现一个接口,但最多只能一个父类或实现一个接口.

//定义一个接口

interface Person {

public void eat();

}

public class AnonymousDemo {

public static void main(String[] args) {

// 使用匿名内部类

Person p = new Person() {

public void eat() {

System.out.println("eat something");

}

};

p.eat();

}

}

4.总结

5.面试题

public class Outer {

public void someOuterMethod() {

// Line 3

}

public class Inner {

}

public static void main(String[] argv) {

Outer o = new Outer();

// Line 8

}

}

/*

* Which instantiates an instance of Inner?

A. new Inner(); // At line 3

B. new Inner(); // At line 8

C. new o.Inner(); // At line 8

D. new Outer.Inner(); // At line 8

*/

答案A.new Inner();等价于this.new Inner();已经存在一个Outer类对象了.

line 8 正确写法,应为: o.new Inner();

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

java内部类选择题_java内部类使用总结相关推荐

  1. java内部类选择题_java内部类详解(附相关面试题)

    说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就来一探究竟. 一.内 ...

  2. java 内部类 作用_java内部类的作用分析

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  3. java 内部类调用_Java内部类使用总结

    1.定义 内部类是指在一个外部类的内部再定义一个类. 内部类作为外部类的一个成员,并且依附于外部类而存在的. 内部类可为static,可用public.protected.private修饰.(而外部 ...

  4. java内部类写法_java内部类怎么写

    一.内部类基础 二.深入理解内部类 三.内部类的使用场景和好处 四.常见的与内部类相关的笔试面试题 若有不正之处,请多谅解并欢迎批评指正. 一.内部类基础 在Java中,可以将一个类定义在另一个类里面 ...

  5. java 精选选择题_Java生产率提示:社区精选

    java 精选选择题 社区已经发言. 我们已将您最好和最出色的生产力技巧汇总到一篇文章中. 我们都有自己的小技巧,可以帮助我们提高工作效率,并提高生产率. 我们使用工具来避免繁琐的日常任务,并运行脚本 ...

  6. java 内部类 抽象类_Java 内部类、匿名内部类、抽象类

    何为内部类 内部类是指 在一个类中在定义一个类 如: 1.成员内部类 public class F { private int a; public void fun(){ //TODO } publi ...

  7. java内部类规则_Java内部类规则

    Java内部类分为 成员内部类 和 局部内部类 一.成员内部类也即实名内部类 又分为 非静态实名内部类 和 静态实名内部类 1.实名内部类可以看做外部类的成员 , 因而可以具有 private .默认 ...

  8. java 多线程 选择题_Java多线程之三道多线程练习题

    三道多线程练习题 接下来,我们来做三道题: 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个 ...

  9. java框架选择题_JAVA三大框架测试题.doc

    框架阶段测试卷 选择题(共50题,每题2分,满分100分) 1.选出不是Restrictions方法的选项(D ). A.eq() B.gt() C.like() D.isNULL() 2.已知系统中 ...

最新文章

  1. 淘宝服务端并发分布式架构演进之路
  2. 398. Random Pick Index - LeetCode
  3. sizzle分析记录:getAttribute和getAttributeNode
  4. 出国留学想申请国家留学基金委的奖学金?传说中的csc! 从这里入手就对了!
  5. 如何查看linux系统的体系结构
  6. asp.net html2canvas,Vue 结合html2canvas和jsPDF实现html页面转pdf
  7. HDU2074 叠筐【打印图案】
  8. win7安装中文语言包
  9. SEO关键词优化 - 利用免费资源刷排名
  10. 使用Arduino和Node.js实现网页界面控制LED的亮度
  11. 5G无线技术基础自学系列 | 5G RAN网络架构关键技术
  12. java 实现搜索附近人功能
  13. day3.python基础中下
  14. google gcr.io、k8s.gcr.io 国内镜像
  15. 微信授权登录的多帐号问题
  16. 摄像机,光源和阴影 -----OGRE 3D 1.7 Beginner‘s Guide中文版 第四章
  17. Windows进程简介
  18. 交易系统开发(十)——FIX协议
  19. 企业用进销存仓储管理软件流程拆解
  20. 文字到底应该如何雕琢

热门文章

  1. Python suds error “'NoneType' object has no attribute 'promotePrefixes'”
  2. 1-物联网开发标配方案(预期方案使用说明和演示)
  3. 笔记:后端 - Redis
  4. Microsoft 推出在AzureApp Service上支持Windows容器的公开预览版
  5. MetaModelEngine:域模型定义
  6. 根据netmask快速判断是否在一个网域
  7. 【SQL Sever】将SQL Sever中的一个数据表的数据导出为insert语句
  8. 深入理解Java多态性
  9. 天津和塘沽两天一夜自由行(第一天)
  10. 给csdn-blog开发组的建议(Kevins)