Java学习笔记(十二)面向对象---内部类
内部类的访问规则
- 内部类可以直接访问外部类中的成员,包括私有成员。
因为内部类中持有了一个外部类的引用,格式为:外部类名.this - 外部类要访问内部类,必须要建立内部对象。
class Outer { //外部类
private int x = 1;
class Inner{ //内部类
int x = 2;
void function() {
int x = 3;
System.out.println(x);
System.out.println(this.x);
System.out.println(Outer.this.x);
}
}
void method() {
Inner in = new Inner();
in.function();
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer out = new Outer();
out.method();
Outer.Inner in = new Outer().new Inner();
in.function();
}
}
运行结果:
3
2
1
3
2
1
访问
- 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。
格式: 外部类名.内部类名 变量名 = 外部类对象.内部类对象; - 当内部类在成员位置上,就可以被成员修饰符所修饰。
例如:private,将内部类在外部类中进行封装。
static:使得内部类具有static的特性。(当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问的局限。)
静态内部类
- 在外部其他类中,如何直接访问静态内部类的非静态成员
class Outer {
private static int x = 1;
static class Inner {
void function() {
System.out.println(x);
}
}
}
public class InnerDemo2 {
public static void main(String[] args) {
new Outer.Inner().function();
}
}
- 在外部其他类中,如何直接访问静态内部类的静态成员
class Outer {
private static int x = 1;
static class Inner {
static void function() {
System.out.println(x);
}
}
}
public class InnerDemo3 {
public static void main(String[] args) {
Outer.Inner.function();
}
}
- 当内部类中定义了静态成员,该内部类必须也是静态的
以下代码编译会导致编译错误
class Outer {
private static int x = 1;
class Inner { //此内部类中定义了静态成员但是此内部类不为静态
static void function() {
System.out.println(x);
}
}
}
public class InnerDemo3 {
public static void main(String[] args) {
Outer.Inner.function();
}
}
- 当外部类中的静态方法访问内部类时,内部类也必须是静态的。
内部类的定义原则
当描述一个事物时,这个事物的内部有事物,此时这个内部的事物需要使用内部类来描述。
局部内部类
- 内部类定义在局部时:
- 不可以被成员修饰符修饰。
- 可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部变量,只能访问被final修饰的局部变量。(目前版本的jdk中,final可以省略)
class Outer {
void method(final int x) {
class Inner {
void function() {
System.out.println(x);
}
}
new Inner().function();
}
}
public class InnerDemo4 {
public static void main(String[] args) {
Outer out = new Outer();
out.method(7);
out.method(8);//因为局部变量在栈内存中,每次一调用入栈,使用结束出栈。所以虽然是被final修饰,但是仍然可以重复调用。
}
}
运行结果:
7
8
匿名内部类
- 匿名内部类其实是内部类的简写格式。
- 定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。 - 匿名内部类的格式:new 父类或者接口(){定义子类的内容}
abstract class Abs {
abstract void method();
}
class Outer {
int x = 3;
/*class Inner extends Abs {
@Override
void mthod() {
System.out.println(x);
}
}*/
public void function() {
//new Inner().mthod();
new Abs() {
@Override
void method() {
System.out.println(x);
}
}.method();
}
}
public class InnerDemo5 {
public static void main(String[] args) {
new Outer().function();
}
}
运行结果
3
以上代码将注释部分,用匿名内部类的形式体现了出来。
- 匿名内部类是一个匿名子类对象。可以理解为带内容的对象。
- 匿名内部类中定义的方法最好不要超过3个。
- 如果一个类既没有实现接口也没有继承父类,可以使用Object类来创建匿名内部类。
例如:
public class InnerClassTest {
public static void main(String[] args) {
new Object() { //如果左边有Object类型引用(Object ob = ),将无法调用method方法
public void method() {
System.out.println("method run");
}
}.method();
}
}
练习
interface Inter {
void method();
}
class Test {
//补足代码,通过匿名内部类
}
public class InnerClassTest {
public static void main(String[] args) {
Test.function().method();
}
}
分析 Test.function().method(); 这行代码可以发现function()应该是Test类中一个静态方法,function()方法后面还有一个method()的调用,说明调用function()方法应是返回了一个对象而且是Inner类型的对象,从而才能继续调用method()方法。
可以得到以下代码:
interface Inter {
void method();
}
class Test {
//补足代码,通过匿名内部类
static Inter function() { //这里返回值类型为Inner
return new Inter(){
@Override
public void method() {
System.out.println("Hello World");
}
};
}
}
public class InnerClassTest {
public static void main(String[] args) {
Test.function().method();
}
}
Java学习笔记(十二)面向对象---内部类的更多相关文章
- Java学习笔记十二:Java中方法的重载
Java中方法的重载 什么是方法的重载呢? 如果同一个类中包含了两个或两个以上方法名相同.方法参数的个数.顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了.如下所示 4 个方法名称都为 s ...
- Java学习笔记十二--集合(三)
第一节课 返回值 方法名 作用 void add(index,elemnet) 在指定的索引处添加元素 object get(index) 返回指定索引处的元素 int indexOf(object) ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
- python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL
python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...
- Go语言学习笔记十二: 范围(Range)
Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...
- 【Java学习笔记之二十五】初步认知Java内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面 ...
- java jvm学习笔记十二(访问控制器的栈校验机制)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...
- Java学习笔记(二)——Java操作properties文件
[前面的话] 前段时间在学习和玩java web相关的东西,对于这些技术,一边学习,一边做东西,一边总结,希望可以一边成长和有所收获.有时总是思考太多反而成为了前进的阻力,所以对于生活还是简单一些,不 ...
- 从.Net到Java学习第十二篇——SpringBoot+JPA提供跨域接口
从.Net到Java学习系列目录 最近又撸了半个月的前端代码,做app离线存储,然后又花了一周去将过去的wcf项目转webapi,java又被落下了,总感觉我特么像斗地主中的癞子牌,变来变去..... ...
随机推荐
- rabbitmq安装(ubuntu)
本文大量复制自:https://blog.csdn.net/qq_22638399/article/details/81704372 # 安装erlang apt-get install erlang ...
- 【原创】关于pyinstaller打包的程序执行出错问题,pyinstaller3.5只支持matplotlib3.0.2已经解决
之前,在用pyinstaller打包一个python程序时没有问题,后来不知道什么原因,再打包时出现了所谓的pyinstaller打包报错: RecursionError: maximum recur ...
- 关于将sublime中的代码高亮导出到博客中
第一步:打开sublime编辑器,用快捷键ctrl+shift+p调出control panel,在出现的输入框中输入install,按回车键 第二步:然后输入插件名称sublimehighlight ...
- R语言入门:使用RStudio的基本操作
R语言在人工智能,统计学,机器学习,量化投资,以及生物信息学方面有着十分广泛的运用.也是我大学的必修课,因此这里梳理一些有关R语言的知识点,做做记录. 首先我们需要知道R语言的工作区域,R语言默认的工 ...
- JVM和线程池
本文链接:https://blog.csdn.net/liuwenliang_002/article/details/90074283 ————————————————版权声明:本文为CSDN博主「3 ...
- PHP版常用算法
PHP版常用算法最近准备面试的资料,顺便整理一下以前的基本算法,写个DEMO记录一下 //冒泡//逐行对比,满足条件则交换function bubbleSort($arrData,$sort = 'd ...
- exsi 6.7u2 不能向winows虚拟机发送ctrl+alt+del
1. 遇到过可以安装它的浏览器插件启动控制台登录就可以了. 2. 下载官方的客户机远程工具“VMware vSphere Client”才行. 3. 直接选择alt+del+insert 键盘即可代替 ...
- gulp常用插件之gulp-cache使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-cache这是一款基于临时文件的gulp缓存代理任务. 更多使用文档请点击访问gulp-cache工具官网. 安装 一键安装不多解释 n ...
- php函数的巧妙应用
直接切入正题: 1.extract();函数从数组中把变量导入到当前的符号表中 对于数组中的每个元素,键名用于变量名,键值用于变量值. 第二个参数 type 用于指定当某个变量已经存在,而数组中又有同 ...
- C# 引入Sqlite 未能加载文件或程序集“System.Data.SQLite
个人博客 地址:https://www.wenhaofan.com/article/20190501224046 问题 在Visual Studio 中 使用NuGet 通过 install-pack ...