内部类:
外部类与内部类的private 元素可以相互访问。
内部类看成外部类的一个对象来访问。
方法中创建内部类
方法的某个作用域中创建内部类
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.6 匿名内部类
1.在匿名内部类末尾是分号,是标志表达式的结束,而并不是内部类的结束,恰好表达式的结束。
2.在匿名内部类中不可能有,有名的构造器,但是通过实例初始化,能达到为匿名内部类创建构造器的效果。
(实例初始化的效果就是构造器而且你不能重载实例初始化方法)
3.匿名内部类不能即扩展类又实现接口。(如果实现接口也只能实现一个)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.6.1 再访工厂方法
public class Outer {
private int i;
private void g(){
System.out.println("g()");
}
public void f(){
//匿名内部类
new Object(){
private void h(){
for (;i < 3;i++)
System.out.println("i = " + i);
}
}.h();
System.out.println("f()");
}
public static void main(String[] args) {
// 创建匿名内部类的对象并且调用它的方法
test11_2.Outer outer = new Outer();
outer.f();
}
}
public class test.Test {
public test.SimplyInterface get(){
return new test13.SimplyInterface(){
// 不用 implements ,直接把接口的方法写进匿名内部类
@Override
public void f() {
System.out.println("f()");
}
};
}
public static void main(String[] args) {
test.Test test = new test13.Test();
test.get().f();
}
}
public interface test.SimplyInterface {
void f();
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.7 嵌套类(它的类类似与一个static 方法)
1.不需要内部类对象与其外围类对象之间又联系,那么可以将内部类声明为static,这样的类常称为嵌套类。
2.普通内部类对象隐式的保存一个对外部类的引用,
嵌套类:要创建嵌套类的对象,不需要外围类对象。
不能从嵌套内部类中访问非静态的外围类对象。
普通内部类:其字段与方法,只能放在类外部的层次上,所以普通内部类不能有static数据和static字段,也不能包含嵌套类。
但嵌套类可以包含所有这些东西。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public class Test {
// 注意二者访问方式的不同
public static void main(String[] args) {
// 注意编译生成的.class文件的名字
new Nested1().f();
new Nested1.Nested2().g();
Test t = new Test();
Test.Nested1 nd1 = new Nested1();
nd1.f();
Test.Nested1.Nested2 nd2 = new Nested1.Nested2();
nd2.g();
}
// 嵌套类
static class Nested1{
static class Nested2{
void g(){
System.out.println("Test.Nested1.Nested2.g()");
}
}
void f(){
System.out.println("Test.Nested1.f()");
}
}
// 普通内部类
class Inner1{
class Inner2{
public void g(){
System.out.println("Test.Inner.Inner2.g()");
}
}
public Inner2 getInner2(){
return new Inner2();
}
public void f(){
System.out.println("Test.Inner.f()");
}
}
public Inner1 getInner1(){
return new Inner1();
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.7.1 接口内部的类
1.正常情况下接口内部是不可以放代码,但嵌套类可以作为借口的一部分,放在接口中的任何类都自动的是public和static的,
因为类是static的,只是将嵌套类置于接口的命名空间内,并不违反接口的规则。
创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用。
public interface NestedInterface {
class Nested{
public void f(){
System.out.println("NestedInterface.ClassB.f()");
}
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public interface I {
void g();
void f();
class Nested{
static void call(I impl){
System.out.println("I.g()");
impl.g();
System.out.println("I.f()");
impl.f();
}
}
}
public class Test {
public static void main(String[] args) {
I impl = new I(){
public void g(){}
public void f(){}
};
I.Nested.call(impl);
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.7.2 从多层嵌套类中访问外部类得成员
1.一个内部类被嵌套多少层并不重要,只要它能透明的访问所有它所嵌入的外围类的所有成员。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.8 为什么需要内部类
1.内部类提供了某种进入外部类的窗口。
2.每个内部类都能都能独立的继承一个接口的实现,所以一个外部类是否实现了某个接口,对内部类并无影响。
3.内部类实现了“多重继承”
4.内部类还可以获得一些其它的特征
1)可以有多个实例,每个实例都有自己的状态信息,并且与外部对象的信息相互独立,
2)单个外部类,可以让多个内部类以不同的方式实现一个接口,或继承同一个类。
3)创建内部类对象的时刻,不依赖外围类对象的创建。
4)内部类就是一个独立的实体,没有is-a关系
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.8.1 闭包与回调
1.闭包(closure) 是一个可调用的对象,它记录了对象的信息,这些信息源来自于创建它的作用域。
可以看出内部类是面向对象的闭包,因为它不仅包含外围类对象的信息,还自动拥有一个指向一个此外围类对象的引用。
(在此作用域内部类包含所有成员的操作权限包括private)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.8.2 内部类控制框架
1.内部类用来解决问题所需的各种action()
2.内部类很容易访问外围类的任意成员。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.9 内部类的继承
public class OuterTwo {
// 报错
/*class InnerTwo extends OuterOne.InnerOne{
public InnerTwo(int i) {
super(i);
}
}*/
class InnerTwo extends OuterOne.InnerOne{
public InnerTwo(OuterOne oo,int i) {
oo.super(i);
}
public void f(){
System.out.println("OuterTwo.InnerTwo.f(0");
super.f();
}
}
public static void main(String[] args) {
OuterOne oo = new OuterOne();
OuterTwo ot = new OuterTwo();
OuterTwo.InnerTwo it = ot.new InnerTwo(oo,47);
it.f();
}
}
public class OuterOne {
class InnerOne{
private int i = 1;
public InnerOne(int i){
System.out.println("OuterOne.InnerOne");
}
public void f(){
System.out.println("Outer.InnerOne.f()");
}
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.10 内部类可以被覆盖吗?
覆盖内部类就好像是一个外围类的方法,其实并不起什么作用。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.11 局部内部类
典型的方式是在一个方法体中创建,局部内部类是不能有访问说明符的,因为它不是外围类的一部分,
但它可以访问当前代码块内部的常量以及所有成员。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10.12 内部类标识符
$,产生的文件都是自动与平台无关。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
总结
什么情况下用接口,什么情况下用内部类