0027 Java学习笔记-面向对象-(非静态、静态、局部、匿名)内部类
内部类
- 内部类就是把一个类写在另一个类的内部
- 用途:
- 如果一个类只希望它被某一个类访问,那么可以把它定义在另一个类的内部,并用private修饰
- 内部类可以访问它所在外部类的private成员;但所在的外部类的成员不能直接访问内部类的数据
- 内部类适合于创建那些仅需要一次使用的类
- 内部类除了可以用省略和public外,还可以用private/protected/static修饰
- 非静态内部类不能拥有静态成员
内部类的分类
- 成员内部类:
- 非静态内部类:没用static修饰
- 静态内部类:用static修饰
- 局部内部类:
- 成员内部类是5大类成员之一;局部内部类和匿名内部类则不是
非静态内部类
- 非静态内部类不用static修饰,属于外部类的对象而不是类本身;非静态内部类寄生在一个外部类对象上;在外部类外部创建内部类的对象时,要先创建外部类的对象
- 内部类可以访问所在外部类的任意成员,即使是private修饰的,因为非静态内部类对象里保存了它所寄生的外部类的对象的引用。也就是说有了非静态内部类的对象,那么必定有它的外部类的对象
- 外部类不能直接访问内部类成员,必须创建对象
- 外部类的静态成员不能访问非静态内部类,包括其变量、创建实例等
- 非静态内部类不能拥有静态成员:?为啥
- 非静态类的对象必定寄生在它外部类的对象里,因此内部类才能访问到外部类的私有成员
- 重名变量:外部类的成员变量;内部类的成员变量;内部类的局部变量,见代码:
package testpack;
public class Test1{
public static void main(String[] args) {
A a=new A();
a.show();
}
}
class A{
private String str="外部类的成员变量";
class B{
public String str="内部类的成员变量";
public void show(){
String str="内部类的局部变量";
System.out.println(str); //局部变量依次覆盖前面的成员变量
System.out.println(this.str); //通过this.变量名访问
System.out.println(A.this.str); //通过外部类名.this.变量名访问
}
}
public void show(){
new B().show();
}
}
静态内部类
- 静态内部类用static修饰
- 静态内部类属于类,非静态内部类属于外部类的对象
- 静态内部类可以包含静态和非静态成员,可以访问外部类的静态成员,但不能访问非静态成员
- 可以在外部类的所有方法、初始化块中创建静态内部类的对象
- 外部类得通过静态内部类的类名或者对象调用静态内部类的类成员或者实例成员
接口中定义内部类
- 接口中可以定义内部类,默认public static修饰,所以只能是静态内部类
- 接口中定义内部类一般没啥意义
内部类的使用
- 在外部类中使用内部类
- 可以在外部类中声明内部类类型的变量、创建内部类的实例
- 外部类得通过创建内部类的实例才能访问到内部类的成员,
包括private成员 - 静态成员不可使用非静态内部类
- 可以在外部类中定义内部类继承另一个内部类
- 在外部类的外部使用非静态内部类
- 类的四个访问权限修饰,这时候就起作用了;private修饰的内部类在外部类的外部就访问不了了
- 定义内部类类型的变量:OuterClass.InnerClass varName
- 创建内部类的对象:new OuterClass().new InnerClass().也就是说要先创建外部类对象,再调用内部类的构造器创建内部类的对象。内部类的构造器得通过外部类的对象来调用
- 继承一个内部类:特别注意,因为子类默认要调用父类的构造器,而内部类的构造器要通过外部类对象调用,因此在子类构造器中必须得有外部类的对象,可以将外部类对象作为参数传入子类的构造器
class Outer{
class Inner{
Inner(){
System.out.println("内部类构造器");
}
}
}
class subInner extends Outer.Inner{
subInner(){
new Outer().super(); //继承内部类,得通过外部类的对象调用内部类的构造器
}
}
- 在外部类以外使用静态内部类
- 可以在外部类的外部创建静态内部类的对象:new OuterClass.InnerClass()
- 因为静态内部类属于类,不需创建外部类的对象来创建内部类对象
- 继承内部类的情况下,直接用super()即可调用内部类父类的构造器
public class Test1{
public static void main(String[] args) {
subInner sb=new subInner();
Outer.Inner oi=new Outer.Inner();
oi.show();
}
}
class Outer{
static class Inner{
Inner(){
System.out.println("内部类无参构造器");
}
Inner (String str){
System.out.println("内部类有参构造器");
}
void show(){
System.out.println("这是内部类的show()方法");
}
}
}
class subInner extends Outer.Inner{
subInner (){
super("ABC"); //直接用super()即可调用内部类父类的构造器
}
}
局部内部类
- 局部内部类比较鸡肋
- 局部内部类定义在一个方法的内部,在方法内部有效
- 不能使用static和访问修饰符
匿名内部类
- 匿名内部类适用于只需要一次使用的类,定义一个匿名内部类时,就会创建一个实例,然后类的定义就消失了,不能重复使用
- 匿名内部类实际上就是一个子类对象,在定义子类的同时创建子类的对象,名字就跟父类或父接口相同
- 用法:
- 匿名内部类只能实现一个接口,或者继承一个类,当实现一个接口时不能传入参数
- 匿名内部类不能是抽象类
- 匿名内部类不能定义构造器,因为这个类就没有名字,可以用初始化块完成构造器完成的初始化工作
- 多用于创建一个某接口类型的对象,
- 一般用于简化书写,很少使用,接口或父类中只有一两个方法的时候才适合
- 调用匿名内部类的方法:直接在定义好之后.方法名()
- 1.8之后,如果一个局部变量被匿名名内部类访问,那么该变量默认有final修饰,因而不能二次赋值
- 匿名内部类示例:
package testpack;
public class Test1{
public static void main(String[] args) {
ProcessArray pa=new ProcessArray();
int[] target={5,35,-2,35,-21};
pa.process(target, new Command(){ //匿名内部类实现一个接口Command,不能传入参数
public void process(int[] target){
int sum=0;
for (int tmp:target) {
sum+=tmp;
}
System.out.println("数组元素总和: "+sum);
}
});
}
}
interface Command{
void process(int[] target);
}
class ProcessArray{
public void process(int[] target,Command cmd){
cmd.process(target);
}
}
其他
- 非静态内部类不能拥有静态成员,为啥?
- 创建外部类对象的时候,会先进行类的初始化,内部类会一起执行吗
0027 Java学习笔记-面向对象-(非静态、静态、局部、匿名)内部类的更多相关文章
- 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- Java学习笔记(三)——静态导入,package-info,Fall-through
[前面的话] 算是真正的放松了好几天时间,没有看任何书,没有任何任务,今天是过完年后的第一天上班时间,我又开始了我的学习之路,感觉还没有老,怎么心态越来越平静了,进入工作状态,就好好努力工作,新的一年 ...
- 0029 Java学习笔记-面向对象-枚举类
可以创建几个对象? n多个:大部分的类,都可以随意创建对象,只要内存不爆掉 1个:比如单例类 有限的几个:采用单例类的设计思路,可以只允许创建少数的几个特定的对象:还有就是枚举类. 创建少数几个对象, ...
- Java学习笔记——static关键字与静态的使用方法
static:可以修饰成员变量和成员方法. 当变量被static修饰后,则其可以直接被类名调用.类名.成员. static特点: 随着类的加载而加载: 优先于对象存在: 被所有的对象共享,节省空间,但 ...
- 程序设计基础·Java学习笔记·面向对象(下)
Java程序设计基础之面向对象(下) (补充了上的一些遗漏的知识,同时加入了自己的笔记的ヾ(•ω•`)o) (至于为什么分P,啊大概是为了自己查笔记方便(?)应该是("` 3′") ...
- 程序设计基础·Java学习笔记·面向对象(上)
Java程序设计基础之面向对象(上) (自适应学习进度而进行记录的笔记,希望有一些小小的用处吧(^∀^●)ノシ) (新人上路,望多指教,如有错误,望指正,万分感谢(o゚v゚)ノ) 目录 一.面向对象 ...
随机推荐
- 【jQuery小实例】js 插件 查看图片
---本系列文章所用使用js均可在本博客文件中找到. 像淘宝一样,鼠标放在某一件商品上,展示大图信息,甚至查看图片的具体部位.给人超炫的效果,这种效果实现基于js文件和js插件.大致可以分为三步,添加 ...
- 数据库SQL Service 2014中文版的安装和配置教程
一.我的电脑环境 1.windows8.1(64位) 2.之前电脑没有安装数据库的软件 二.装机之前准备(我这儿提供百度云保存和下载) 1.下载一个“Sql service 2014中文版” http ...
- js构建ui的统一异常处理方案(二)
上一篇文章,我分析了同步代码做异常处理是基于责任链模式,而通过try.catch等语句可以很容易地实现这种责任链模式.但是如果是异步调用,我们无法直接通过try.catch语句实现责任链模式,并且通过 ...
- Mybatis高级查询之关联查询
learn from:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Result_Maps 关联查询 准备 关联结果查询(一对一) resul ...
- JAVA常见面试题之Forward和Redirect的区别
用户向服务器发送了一次HTTP请求,该请求可能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉不到请求转发的.根据转发方式的不同,可以区分为直接请求转发 ...
- IOS客户端UIwebview下web页面闪屏问题
基于ios客户端uiwebview下的web页面,在其内容高度大于视窗高度时,如果点击超过视窗下文档的底部按钮,收缩内容高度,会发生闪屏问题. 外因是由文档的高度大于视窗的高度所致,本质原因未知. 解 ...
- 【WCF】WCF中的InstanceContext与ConcurrencyMode【转】
一.前言 最近忙于公司的在线升级项目,一个人要负责公司四大产品的在线升级,这四个产品是在Revit中以插件形式存在的,目前基于WCF来实现.等客户总量突破5万了,再重新用socket实现. 由于有服务 ...
- WPF DataGrid 鼠标双击选中的DataGridRow及Row数据
设置DataGrid的MouseDoubleClick事件 代码 //DataGrid鼠标双击事件 Private void dataGrid_MouseDoubleClick(object send ...
- mvc实现上传图片(上传和预览)webuploader
笔者看到mvc最近比较流行,而很多使用一些比较旧的的方法上传图片,再次安利一下百度的webuploader控件吧 webuploader第一步要先下载一些插件这点可以在webuploader官网上下载 ...
- jquery css事件编程 尺寸设置
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...