Java学习笔记20---内部类之对成员内部类的补充说明(一)
上篇文章--笔记19简要介绍了成员内部类、局部内部类和匿名内部类,下面对成员内部类再补充一些内容。
主要有以下6点:
1.成员内部类不可以有静态成员,成员变量为static final时除外
2.外部类不可以直接访问成员内部类的成员变量或调用成员内部类的成员方法
3.成员内部类可以无限制的访问外部类的成员变量、调用外部类的成员方法
4.成员内部类的成员与外部类成员同名时,内部类成员会屏蔽外部类的同名成员
5.成员内部类本身可以由访问权限修饰符修饰
6.成员内部类的成员变量和成员方法也可以由访问权限修饰符修饰
(注:时间有点晚了,5、6条下篇再写吧)
作者: 蝉蝉
请尊重作者劳动成果,转载请在标题注明“转载”字样,并标明原文链接:
http://www.cnblogs.com/chanchan/p/8254124.html
下面分别展开说明:
1.成员内部类不可以有静态成员,成员变量为static final除外
示例:
//笔记19:内部类--成员内部类--不能有静态成员,成员变量为static final时除外
class InnerClass {
String name = "li";
String inname;
static String ingender = "female"; //不能有静态成员,除非声明为static final
void testStFi() {
System.out.println("ingender:" + ingender);
} //不能有静态成员方法
static void testStFiMeth() {
System.out.println("成员内部类的静态成员方法");
}
} public static void main(String[] args) { Person per = new Person();
Person.InnerClass inC = per.new InnerClass(); //笔记19:内部类--成员内部类--4不能有静态成员,除非声明为static final
inC.testStFi();
}
编译时会报出下面的错误:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The field ingender cannot be declared static in a non-static inner type, unless initialized with a constant expression
The method testStFiMeth cannot be declared static; static methods can only be declared in a static or top level type
分析:
(1).根据错误提示,成员内部类不能有静态成员变量,除非该成员由常量表达式初始化;
大家知道,由static final修饰的成员变量其值不可改变,是编译时常量,所以把
static String ingender = "female";
改为:
static final String ingender = "female";
再编译就可以通过了。
(2).成员内部类为什么不可以有静态成员变量呢?
1).对于外部类来说,当类尚未加载时,访问静态成员变量或创建一个对象都可以引起类的加载,而类加载时就会为静态成员变量分配空间。
访问外部类静态成员变量时,如果类尚未加载,则会先加载类,并为静态成员变量分配空间,然后就可以访问了;如果类已经加载过了,说明静态成员变量已经分配过内存了,直接访问就可以了。所以,外部类不论什么情况下都可以正确的访问其静态成员变量。(参考笔记11)
2).而对于成员内部类来说,外部类加载时,并不会被自动加载;只有外部类的一个对象在首次创建成员内部类的对象时,才会引起成员内部类的加载。假设成员内部类有静态成员变量,如果在成员内部类加载之前就需要访问其静态成员变量呢?很显然,在类加载之前,其静态成员变量是未分配内存的,这时候要访问的是一个并不存在的变量,就会出错。所以,成员内部类是不能有静态成员变量及静态成员方法的(道理类似)。
参考图片更直观:

(3).延伸:外部类与成员内部类的加载方式 和 父类与子类之间的加载方式是不一样的
1).成员内部类与外部类是附属与被附属的关系,必须通过外部类对象来创建成员内部类的对象,所以可以先加载外部类,等需要的时候再加载成员内部类。且一个外部类对象可以创建多个内部类对象,是一对多的关系。最近每天睡觉前小姑娘都要听“泥娃娃”,“泥娃娃,泥娃娃,一个泥娃娃,也有那眉毛,也有那眼睛,眼睛不会眨...”。泥娃娃像人一样,但又比人少了点什么,就把人看成外部类,泥娃娃就是人的成员内部类,哈哈,人创造了泥娃娃,而且可以创造多种多样的泥娃娃。
2).而子类与父类是is-a的关系,两个类相互独立,但可以看成子类对象里隐含了一个父类对象。首次使用子类时,要先加载父类并为其静态成员变量分配内存,再加载子类并为其静态成员变量分配内存,然后依次初始化成员变量,调用构造方法等等(可参考笔记11)。所以这里父类、子类都要加载。
几者的关系见下图:

2.外部类不可以直接访问成员内部类的成员变量或调用成员内部类的成员方法
示例:
类Person中定义了一个成员内部类InnerClass,Person的成员方法outerCAccessinC访问InnerClass的成员变量inname。
//成员内部类
class InnerClass {
String name = "li";
String inname; void printInC() {
System.out.println("inner class");
}
} //笔记19:内部类--成员内部类--外部类能访问内部类成员变量、调用成员方法吗?
public void outerCAccessinC() {
System.out.println("inname:" + inname);
} public static void main(String[] args) { Person per = new Person(); //笔记19:内部类--成员内部类--外部类不能访问内部类成员变量或调用成员方法
per.outerCAccessinC();
per.printInC();
}
结果出现下述错误:
第13行提示如下的错误:
inname cannot be resolved to a variable
22行提示如下的错误:
The method printInC() is undefined for the type Person
这说明外部类是无法直接访问成员内部类的成员变量或成员方法的。
反面来看,假如外部类可以直接访问成员内部类的成员,还以上面的程序为例,创建一个Person类对象per,per调用方法outerCAccessinC,由于这时尚未创建成员内部类的对象,其成员变量当然也没有分配空间,这时per将访问一个不存在的变量inname,这是不允许的。
所以成员内部类的成员对外部类是不可见的,外部类是无法直接访问成员内部类的成员的。
3.成员内部类可以无限制访问外部类的成员变量及调用外部类的成员方法
示例:
类Person定义了若干个成员变量及一个成员内部类InnerClass。成员内部类InnerClass中定义了成员方法testVarMeth,testVarMeth访问及调用了外部类Person的多个成员变量和成员方法。
String name;
int age;
String gender; public String education; //防问权限修饰符
private String hobby;
protected String residence; static String citizenship = "Chinese"; class InnerClass { void testVarMeth() {
System.out.println("name:" + name);
System.out.println("education:" + education);
System.out.println("hobby:" + hobby);
System.out.println("residence:" + residence);
System.out.println("citizenship:" + citizenship);
System.out.println("age:" + getAge());
System.out.println("gender:" + getGender());
}
} public static void main(String[] args) { Person per = new Person();
Person.InnerClass inC = per.new InnerClass(); //笔记19:内部类--成员内部类--内部类访问外部类成员变量、调用成员方法
inC.testVarMeth();
}
输出结果为:
name:null
education:null
hobby:null
residence:null
citizenship:Chinese
age:0
gender:null
从结果可以看出,成员内部类可以随意访问或调用外部类的成员变量或成员方法,与访问权限及类型等都没有关系。
4.成员内部类的成员与外部类成员同名时,内部类成员会屏蔽外部类的同名成员
示例:
对2中的程序稍加修改,为成员内部类InnerClass添加一个与Person同名的成员变量name:
String name = "li";
再执行程序的话,输出结果变为:
name:li
education:null
hobby:null
residence:null
citizenship:Chinese
age:0
gender:null
可以看出,如果成员内部类与外部类有同名的成员的话,成员内部类内部会屏蔽掉外部类的同名成员,也即,外部类的同名成员对成员内部类是不可见的。
如果一定要在内部类中使用外部类的同名成员变量的话,可以使用下面的语句:
System.out.println("name:" + Person.this.name);
即,用 外部类.this.同名成员变量名 即可访问了。
Java学习笔记20---内部类之对成员内部类的补充说明(一)的更多相关文章
- Java学习笔记21---内部类之对成员内部类的补充说明(二)
上篇文章--笔记20补充说明了前四点,这里接着来说剩下的两点. 要点如下: 5.访问权限修饰符可以修饰成员内部类 1).访问权限修饰符对内部类的访问限制与外部类的一般成员遵循一样的规则,具体请参考笔记 ...
- Java学习笔记之---内部类
Java学习笔记之---内部类 (一)成员内部类 内部类在外部使用时,无法直接实例化,需要借助外部类信息才能实例化 内部类的访问修饰符可以任意,但是访问范围会受到影响 内部类可以直接访问外部类的成员, ...
- Java学习笔记19---内部类之简介成员内部类、局部内部类及匿名内部类
内部类,顾名思义,即定义在某个类内部的类,称包含该内部类的类为外部类. 从定义的位置来说,分为成员内部类和局部内部类:从类的特征来说,分为匿名内部类和静态内部类. 今天先简要介绍一下前三种内部类的定义 ...
- Java学习笔记之——内部类
内部类 形式:把一个类定义在一个类的内部. 分为:成员内部类和匿名内部类重点掌握 a) 成员内部类 b) 静态成员内部类 c) 匿名内部类 d) 局部内部类 (1)成员内部类: Java的语言是面向对 ...
- Java学习笔记:内部类/匿名内部类的全面介绍
编写java程序时,一般一个类(或者接口)都是放在一个独立的java文件中,并且类名同文件名(如果类是public的,类名必须与文件名一致:非public得,无强制要求).如果想把多个java类放在一 ...
- 3)Java学习笔记:内部类
什么是内部类 内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的.内部类可为静态,可用protected和private修饰(而外部类只能使用public和 ...
- 【原】Java学习笔记025 - 内部类
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 内部类(嵌套类): ...
- Java学习笔记20(String类应用、StringBuffer类、StringBuilder类)
1.获取指定字符串中大小写和数字的个数: package demo; public class StringTest { public static void main(String[] args) ...
- java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)
集合:集合是Java提供的一种容器,可以用来存储多个数据: 集合与数组的区别:集合的长度是可变的,数组的长度是固定的 集合中存储的数据必须是引用类型数据: ArrayList回顾: public cl ...
随机推荐
- 从durable谈起,我是如何用搜索引擎抓住技术的关键字学习新姿势打开敏捷开发的大门
---又名我讨厌伸手党 我又把个人博客的子标题改为了 你可以在书和搜索引擎找到90%的问题的答案,为什么要问别人?剩下的10%或许没有答案,为什么要问别人? 这是由于最近在网上看到各种伸手,对于我这种 ...
- 2.python的文件类型、变量数值和字符串练习
1.python的文件类型 .源代码 -python 源代码文件以"py"为扩展名,由python程序解释,不需要编译. 2.字节代码(编译的) -python源码文件经编译后生成 ...
- VBScripts and UAC elevation(visa以后的系统)
这两天由于工作须要.在写一些vbs的脚本,才知道.vbs不能像其它可运行文件一样.在 须要提升訪问权限时.弹出UAC窗体.那么,怎样通过UAC提升vbs脚本的訪问权限呢? 查了一些资料,将结果整理一下 ...
- Asp.net mvc 知多少(四)
本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...
- Mybatis中如何将POJO作为参数传入sql
今天在工作时,需要将获取的用户的注册信息插入数据库,开始的做法是将所有的model的属性作为DAO接口的参数,后来想想不对劲,要是有100个属性,那我这个接口岂不是要有100个参数传进来? 于是我就考 ...
- python自动化--文件处理
文件处理 格式 打开 f=open('a.txt',mode='r',encoding='utf-8') 读写 data=f.read() print(data) 关闭 f.close() 流程分析: ...
- RESTful 的通俗解释
转载自知乎,通俗易懂的讲解了RESTful链接:https://www.zhihu.com/question/28557115/answer/48094438 REST -- REpresentati ...
- Python 项目实践二(生成数据)第一篇
上面那个小游戏教程写不下去了,以后再写吧,今天学点新东西,了解的越多,发现python越强大啊! 数据可视化指的是通过可视化表示来探索数据,它与数据挖掘紧密相关,而数据挖掘指的是使用代码来探索数据集的 ...
- (转)为Xcode添加删除行、复制行快捷键
转摘链接:http://www.jianshu.com/p/cc6e13365b7e 在使用eclipse过程中,特喜欢删除一行和复制一行的的快捷键.而恰巧Xcode不支持这两个快捷键,再一次的恰巧让 ...
- Pashmak and Flowers
Pashmak decided to give Parmida a pair of flowers from the garden. There are nflowers in the garden ...