内部类总结

内部类总结:

1、内部类允许在一个类中定义另一个类。它们为类提供一种范围,因为可以使一个类成为另一个类的成员。
2、“顶级嵌套类”—— 一种标识为static的内部类,从技术上来说并不是真正的内部类。因为静态嵌套类
仍然是一个类。
3、事件处理程序可能是这种情况的一个最好的例子,事实上,这也是把内部类添加到该语言的主要原因之一。
4、内部类实例可以访问外部类的所有成员,甚至是private成员(因为内部类也是外部类的一个成员)。
5、class MyOuter {
class MyInner {

}
}
如果编译它:javac MyOuter.java 将产生两个类文件:MyOuter.class、MyOuter$MyInner.class
用普通方式不能访问这个内部类文件,例如java MyOuter$MyInner希望运行这个内部类的main方法。
常规内部类不能有任何类型的静态声明。能够访问内部类的唯一方法是通过外部类的一个实例。
6、要实例化内部类实例,必须要有一个与它相关的外部类实例,它指不能从外部类的static方法或
者从任何其他类的任何其他代码实例化内部类。
(1)在外部类代码中实例化内部类
class MyOuter {
private int x = 7;
public void makeInner() {
MyInner in = new MyInner();
in.seeOuter();
}
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
}
(2)在外部类代码外实例化内部类
从外部类的外部非静态代码中的任何地方建立实例的代码都很简单:
public static void main(String[] args) {
MyOuter mo = new MyOuter();
MyOuter.MyInner inner = mo.new MyInner();
inner.seeOuter();
}
无论main方法是位于MyOuter类中还是某个其他类中(假若其他类可以访问MyOuter),前面代码都是相同的。
如果合为一行,则是:MyOuter.MyInner inner = new MyOuter().new MyInner();
7、在内部类代码内,this引用该内部类的实例。但如何在内部类中访问它的外部类实例呢?
尽管通常情况下内部类代码不需要引用外部类,因为它已经有一个隐含引用,但是如果真的要呢?
class MyOuter {
private int x = 7;
public void makeInner() {
MyInner in = new MyInner();
in.seeOuter();
}
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
System.out.println("Inner class ref is " + this);
System.out.println("Outer class ref is " + MyOuter.this);
}
}
public static void main(String[] args) {
MyOuter.MyInner inner = new MyOuter().new MyInner();
inner.seeOuter();
}
}
8、应用于内部类的成员修饰符
final、abstract、public、private、protected、static、strictfp。
9、方法本地内部类:
class MyOuter2 {
private String x = "Outer2";
void doStuff() {
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
MyInner in = new MyInner();
in.seeOuter();
}
}
(1)方法本地内部类只能在定义该内部类的方法内实例化。
(2)内部类对象不能使用该内部类所在方法的局部变量(不过如果局部变量是final的,则也可以),那为什么呢?
因为不能保证局部变量的存活期与本地内部类对象一样长。
(3)唯一能够应用于本地内部类的修饰符是abstract和final。
(4)在一个静态方法内声明的内部类只能访问该封装类的静态成员。
10、匿名内部类:
(1)可以在方法内、方法的参数内定义。
class Popcorn {
public void pop() {
System.out.println("popcorn");
}
}
class Food {
// 声明Popcorn类型的实例变量p后,声明一个新类,它没有名字,它是Popcorn的子类
Popcorn p = new Popcorn() {
// 建立匿名内部类的关键点:重写父类的一个或多个方法(或设计一个接口的方法)
public void pop() {
System.out.println("anonymous popcorn");
}
}
}
这里要记住的关键一点是Popcorn引用变量不是引用Popcorn实例,而是Popcorn匿名子类的实例。
(2)当涉及到匿名内部类时,多态性在起作用。其含义是什么?
引用变量类型(父类)将不知道关于新方法(定义在匿名子类)的任何内容,因此,如果在匿名
内部类引用上调用父类定义中没有的任何方法,编译出错。
class Horse extends Animal {
void buck() {

}
}
class Animal {
void eat() {

}
}
class Test {
public static void main(String[] args) {
Animal h = new Horse();
h.eat(); // 正确
h.buck(); // 错了
}
}
(3)只能设计一个接口。事实上,一个匿名内部类甚至不能同时扩展一个类和设计一个接口。
11、静态嵌套类也称顶级嵌套类,或静态内部类。但是按照内部类的标准定义,它们根本就不是内部类。
class BigOuter {
static class Nested {

}
}
该类自己并不真正是“静态的”,没有静态类这样的内容。在这种情况下,static修饰符只是说这个嵌套类是
外部类的静态成员。
(1)静态嵌套类不能访问外部类的实例变量和方法。一定要注意静态嵌套类中的代码像非静态(常规)内部类
一样操作。
(2)实例化静态嵌套类:
class BigOuter {
static class Nested {

}
}
class Broom {
public static void main(String[] args) {
BigOuter.Nested n = new BigOuter.Nested();
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值