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又被落下了,总感觉我特么像斗地主中的癞子牌,变来变去..... ...
随机推荐
- Python——20200220Python123冲刺试卷 - 1
知识点:面向对象继承,数组组织,文件操作,数据类型 1.面向对象的继承:继承是指类之间共享属性和操作的性质 2.软件危机的原因不包括:软件成本不断提高 软件危机原因: 软件开发生产率低.软件过程不规范 ...
- Leetcode 与树(TreeNode )相关的题解测试工具函数总结
最近在剑指Offer上刷了一些题目,发现涉及到数据结构类的题目,如果想在本地IDE进行测试,除了完成题目要求的算法外,还需要写一些辅助函数,比如树的创建,遍历等,由于这些函数平时用到的地方比较多,并且 ...
- 【spring boot】SpringBoot初学(8)– 简单整合redis
前言 到目前为止,把项目中需要用到的:properties读取.数据源配置.整合mybatis/JdbcTemplate.AOP.WebService.redis.filter.interceptor ...
- 论文阅读笔记(十七)【ICCV2017】:Dynamic Label Graph Matching for Unsupervised Video Re-Identification
Introduction 文章主要提出了 Dynamic Graph Matching(DGM)方法,以非监督的方式对多个相机的行人视频中识别出正确匹配.错误匹配的结果.本文主要思想如下图: 具体而言 ...
- PHP0006:PHP基础--函数2
如果php后面没有任何html代码就可以 删掉后面的 ?> 符号 file_put_content 是覆盖写入文件信息
- Reg文件操作
注册表REG脚本文件测试 1.新建主键 例如,想在主键[HKEY_CURRENT_USER\Software]下新建一个名叫“新建主键名称”的主键. 可以打开记事本,写入如下内容: Windows R ...
- python--终端工具之subprocess
一. subprocess.getstatusoutput import subprocess cmd = 'ifconfig' def cmds(cmd,print_msg=True): statu ...
- Error: cannot fetch last explain plan from PLAN_TABLE
最近遇到了错误"Error: cannot fetch last explain plan from PLAN_TABLE",于是稍微研究了一下哪些场景下碰到这种错误,具体参考下面 ...
- 对vulnhub靶机lampiao的getshell到脏牛提权获取flag
前言: vulnhub里面的一个靶场,涉及到drupal7 cms远程代码执行漏洞(CVE-2018-7600)和脏牛提权. 靶机下载地址:https://mega.nz/#!aG4AAaDB!CBL ...
- pandas玩转excel-> (1)如何利用pandas创建excel数据文件
#在Anaconda3 的Spyder中 #定义pandas模块为pd import pandas as pd #创建一个新的DataFrame对象,定义这个对象中有两个字段:ID和Name, ...