java面试题之----Java内部类
1.为什么使用内部类?
使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
对于内部类都没有影响
1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
(1)、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独。
(2)、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
(3)、创建内部类对象的时刻并不依赖于外围类对象的创建。
(4)、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
(5)、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
2.内部类分类:
(一).成员内部类:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class Outer{ private int age = 99; String name = "Coco"; public class Inner{ String name = "Jayden"; public void show(){ System.out.println(Outer.this.name); System.out.println(name); System.out.println(age); } } public Inner getInnerClass(){ return new Inner(); } public static void main(String[] args){ Outer o = new Outer(); Inner in = o.new Inner(); in.show(); } } |
1.Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,
如 public 、 protected 、 private 等
2.Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,
如直接访问 Outer 类中的私有属性age
3.定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,
即:内部类 对象名 = 外部类对象.new 内部类( );
4.编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
5.成员内部类中不能存在任何 static 的变量和方法,可以定义常量:
(1).因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,
简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;
非静态内部类的作用域是实例级别
(2).常量是在编译器就确定的,放到所谓的常量池了
★★友情提示:
1.外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法;
2.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,
可以使用 this 关键字,如:Outer.this.name
(二).静态内部类: 是 static 修饰的内部类,
1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
2.如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
3.创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class Outer{ private int age = 99; static String name = "Coco"; public static class Inner{ String name = "Jayden"; public void show(){ System.out.println(Outer.name); System.out.println(name); } } public static void main(String[] args){ Inner i = new Inner(); i.show(); } } |
(三).方法内部类:其作用域仅限于方法内,方法外部无法访问该内部类
(1).局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
(2).只能访问方法中定义的 final 类型的局部变量,因为:
当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量;
==>使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.
局部内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
自己内部的方法调用的实际是自己的属性而不是外部类方法的参数;
防止被篡改数据,而导致内部类得到的值不一致
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/* 使用的形参为何要为 final??? 在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的, 也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的, 毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解 和不可接受的,所以为了保持参数的一致性,就规定使用 final 来避免形参的不改变 */ public class Outer{ public void Show(){ final int a = 25; int b = 13; class Inner{ int c = 2; public void print(){ System.out.println("访问外部类:" + a); System.out.println("访问内部类:" + c); } } Inner i = new Inner(); i.print(); } public static void main(String[] args){ Outer o = new Outer(); o.show(); } } |
(2).对于匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,
该类的定义会立即消失,所以匿名内部类是不能够被重复使用;
(3).使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口;
(4).匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
(5).匿名内部类中不能存在任何的静态成员变量和静态方法,匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法
(6).匿名内部类初始化:使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class OuterClass { public InnerClass getInnerClass(final int num,String str2){ return new InnerClass(){ int number = num + 3; public int getNumber(){ return number; } }; /* 注意:分号不能省 */ } public static void main(String[] args) { OuterClass out = new OuterClass(); InnerClass inner = out.getInnerClass(2, "chenssy"); System.out.println(inner.getNumber()); } } interface InnerClass { int getNumber(); } |
java面试题之----Java内部类的更多相关文章
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- 一线互联网企业常见的14个Java面试题,Java面试题集大全等你拿,颤抖吧程序员!
本文由尚学堂学员们根据自己参加过的面试回忆.总结而成,一线互联网企业常见的14个Java面试题,包括各大互联网企业.创业小公司,互联网企业.传统软件公司.对于刚毕业和想要跳槽的宝宝们,再适用不过啦,赶 ...
- Java面试题:Java中怎么样实现多线程
方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThrea ...
- 转载:[Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
原文:http://www.cnblogs.com/wang-meng/p/5898837.html 一:继承.抽象类与接口区别.访问控制(private, public, protected,默认) ...
- Java面试题系列 ----- Java基础面试题(91道)
更多详情点击查看,点这里!这里!!这里!!! 文末获取所有面试PDF文档! Java概述 1. 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了 ...
- 【Java面试题】12 内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以.如果不是静态内部类,那没有什么限制! 如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码: class Ou ...
- JAVA面试题 浅析Java中的static关键字
面试官Q1:请说说static关键字,你在项目中是怎么使用的? static 关键字可以用来修饰:属性.方法.内部类.代码块: static 修饰的资源属于类级别,是全体对象实例共享的资源: 使用 s ...
- JAVA面试题0 JAVA语言的基本知识
JAVA语言的特点是什么? >面向对象:两个基本概念:类和对象:三大基本特性:封装.继承.多态: >健壮性:java吸收了C/C++的优点,但是去掉了它们影响健壮性的部分,例如指针和内存申 ...
- Java面试题之Java基础
1. JDK 和 JRE 有什么区别? JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台.所有的Java 程序都要在JRE下才能运行.普通用户只需要运行已开 ...
随机推荐
- 一篇Java图片验证码生成的代码
package projectUtil; /** * @author tian * @date 2019/4/1015:58 */ import javax.imageio.ImageIO; impo ...
- Jmeter调试脚本之断言
前言: jmeter中有个元件叫做断言(Assertion),它的作用和loadrunner中的检查点类似: 用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致. ...
- Netflix Hystrix笔记
maven引入 <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hyst ...
- hadoop包含哪些技术?
1.Hadoop包含哪些技术?Common, Avro, MapReduce, HDFS, Pig, Hive, Hbase, ZooKeeper, Sqoop, Oozie. 2.简介Common: ...
- DateTime.Now与DateTime.Today的区别
区别如下图: DateTime.Now: 不仅显示日期 还显示当前时间: DateTime.Today: 只显示当前日期,没有时间
- jenkins启动脚本
[root@localhost system]# cat /etc/init.d/jenkins #!/bin/sh # # SUSE system statup script for Jenkins ...
- https Java SSLException protocol_version的问题解决方法
我们的业务代码里有需要用爬虫爬取商品的图片地址,然后在转到我们的服务器里的过程,中间当然少不了下载图片的过程,最近目标网站有些改变,就是之前http前缀的图片地址部分改成了https,然后就造成了一个 ...
- JQuery对数组的一些操作总结
JQuery对数组的处理非常便捷并且功能强大齐全,一步到位的封装了很多原生js数组不能企及的功能.下面来看看JQuery数组的强大之处在哪. $.each(array, [callback]) 遍历 ...
- 如何使用 MySQL EntityFramework 组件处理 MYSQL PaaS DB
MySQL Database on Azure 是 Azure 平台上推出的 MySQL 云数据库服务,通过全面兼容 MySQL 协议,为用户提供了一个全托管的性能稳定.可快速部署.高可用.高安全性的 ...
- MySQL批量插入多条数据方便测试
批量插入流程 数据库字段 delimiter create procedure doinsert3() begin declare i int; declare j int; ; ; ) do ins ...