第十章 花里胡哨的内部类
不得不说,编程思想真本书的信息量是真的大,有相当多的东西,非常的细节,必须要自己总结之后才会发现收获。
一定要注意书中外部类和外围类的区别。
class AA { class BB {} } class CC {}
AA类与CC类都是外部类,但是只有AA叫外围类。
一、类中的内部类
首先很重要的一点,在类中定义的内部类,是可以在外部类中创建其对象的。但是,在方法和作用域中定义的内部类,一旦出了方法和作用域的范围,这个内部类便不可以在被访问了。
1.在外部类的静态方法中,是一定要指明对象的类型的OuterClass.InnerClass。(看懂没有关系,看列子)
2.要创建内部类对象必须要,要有其外围类对象的引用。(嵌套类可以不必需要)
3.内部类可以访问外围类的所有成员(内部类是可以直接使用外围类成员的)(千万注意不是内部类对象可以访问外围类对象的所用成员,书上说的有不准确的地方),外围类也可以访问内部类的所有成员只不过形式不同。
实例:
class AA { private void printA1() { System.out.println("printA1()"); } public void printA() { System.out.println("printA()"); } class BB { public void printB() { printA1();//证明内部类可以访问外部类的所有成员,而且是直接访问 System.out.println("BB"); } } public BB getBBClass() { return new BB(); } } public class InneratClass { public static void main(String[] args) { // TODO Auto-generated method stub AA a = new AA(); AA.BB b = a.getBBClass(); b.printB(); //b.printA();如果这样写就会报错 } }
结果:
外围类访问内部类私有成员:
class Outer { class Inner { private Inner(int i) {} private void print() { System.out.println("Inner"); } } Inner getInner() { Inner i = new Inner(1); //外围类访问内部类私有成员 i.print(); return i; } } public class CreateInner { public static void main(String[] args) { // TODO Auto-generated method stub Outer o = new Outer(); Outer.Inner i = o.getInner(); } }
4、“.this”返回外围类对象的引用
用法实例:
public class This { class A { This getOuterClass() { return This.this; } } A getAClass() { return new A(); } void print() { System.out.println("This"); } public static void main(String[] args) { // TODO Auto-generated method stub This t = new This(); This.A a = t.getAClass(); This b = a.getOuterClass(); b.print(); } }
5.“.new”创建内部类对象的另外一种方式
方式一:外围类用一个方法返回内部类引用
class Outer { class Inner { void print() { System.out.println("Inner"); } } //创建内部类的第一种方式,在外围类用一个方法返回内部类引用 Inner getInner() { return new Inner(); } } public class CreateInner { public static void main(String[] args) { // TODO Auto-generated method stub Outer o = new Outer(); Outer.Inner i = o.getInner(); i.print(); }
方式二:.new方式
class Outer { class Inner { void print() { System.out.println("Inner"); } } } public class CreateInner { public static void main(String[] args) { // TODO Auto-generated method stub Outer o = new Outer(); Outer.Inner i = o.new Inner(); i.print(); } }
6.向上转型
interface Fruit { void eat(); } class Outer1 { private class Apple implements Fruit{ public void eat() { System.out.println("Apples are good!"); } } Fruit getApple() { return new Apple(); } } public class InnerUpcast { public static void main(String[] args) { // TODO Auto-generated method stub Outer1 o = new Outer1(); Fruit f = o.getApple(); f.eat(); } }
7、继承会把内部类一起继承,内部类就是外围类的一部分,就是它的成员,这一点书里没有说到。
class Fruit1 { class Apple { public void eat() { System.out.println("Apples are good!"); } } } public class StaticInnerClass extends Fruit1{ public static void main(String[] args) { Fruit1 f = new Fruit1(); StaticInnerClass s = new StaticInnerClass(); StaticInnerClass.Apple a1 = f.new Apple(); StaticInnerClass.Apple a2 = s.new Apple(); a1.eat(); a2.eat(); } }
输出:
Apples are good!
Apples are good!
二、方法和作用域中的内部类
类中的内部类是类的一部分;方法和作用域中的内部类也是其一部分,离开了方法和作用域其内部类便不可访问。
方法和作用域中的内部类,与类中的内部类一样需要外围类对象引用。
实例:
public class MethodInner { interface Fruit { void eat(); } Fruit getApple() { class Apple implements Fruit{ public void eat() { System.out.println("Apples are good"); } } return new Apple(); } public static void main(String[] args) { // TODO Auto-generated method stub MethodInner m = new MethodInner(); Fruit f = m.getApple(); f.eat(); } }
三、匿名内部类
匿名内部类一般都是作为临时使用的。
1.匿名内部类如果使用在其外部定义的数据,那么要求这个数据是final的,否则编译器会给出错误。《编程思想》是这么说的,但是经我验证并不会报错。可能是java版本更新换代的原因吧,有出入是很正常的
实例:
public class AnonymityInner { class Fruit { String s; Fruit(final String s) { this.s = s; } void eat() { System.out.println("Fruit is " + s); } } Fruit getApple(String i) { return new Fruit("good") { void eat() { String s = i; System.out.println(s + " Apples"); } }; } public static void main(String[] args) { // TODO Auto-generated method stub String s = "5"; AnonymityInner a = new AnonymityInner(); Fruit f = a.getApple(s); f.eat(); } }
四、嵌套类
1.静态内部类(即嵌套类)中可以定义static成员,而普通的内部类是不准有static成员的。
2.静态内部类不需要外围类的引用来创建对象,它也就失去了外围类引用带来的好处,嵌套类只能够访问外围类的静态成员,类似于静态方法。
使用起来就像是使用类的静态域一样
class Fruit1 { static class Apple { public void eat() { System.out.println("Apples are good!"); } } } public class StaticInnerClass { public static void main(String[] args) { Fruit1.Apple a = new Fruit1.Apple(); a.eat(); } }
接口中的嵌套类:
package innerclass; interface Fruit1 { //接口中的类自动为嵌套类,且是public class Apple { public void eat() { System.out.println("Apples are good!"); } } } public class StaticInnerClass implements Fruit1{ public static void main(String[] args) { StaticInnerClass.Apple a2 =new StaticInnerClass.Apple(); a2.eat(); } }
输出:
Apples are good!
内部类的写法真的是五花八门ε=(´ο`*)))唉