1. 成员内部类分为 静态内部类 和 非静态内部类。
非静态内部类 和 外部类的其他成员一样处理, 非静态内部类可以访问外部类的private的属性,而外部类不能访问非静态内部类的属性,需要实例非静态内部类,然后操作其属性。
外部类对象访问非静态内部类成员时, 可能非静态普通类对象根本不存在,而非静态内部类对象访问外部类成员时,外部类对象一定是存在的。
静态成员不能访问非静态成员。
外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员。
2. 内部类的使用情况。
a. 在外部类中使用内部类: 作为外部类成员,与使用其他普通类类似,只是要注意外部类的静态成员不能使用非静态内部类。
b. 在外部类以外使用内部类:
A.AA aa = new A().new AA(); //非静态内部类
aa.funAA();
A.AB ab = new A.AB(); //静态内部类
ab.funAB();
class A { int a = 0; public class AA { public AA() { } public void funAA() { System.out.println("funAA in classAA"); } } public static class AB { public void funAB() { System.out.println("funAB in classAB"); } } } public class Main { public static void main(String[] args) { // TODO Auto-generated method stub A.AA aa = new A().new AA(); aa.funAA(); A.AB ab = new A.AB(); ab.funAB(); } }
3. 局部内部类。
讲一个内部类在方法里面定义,则这个内部类为局部内部类,只有在这个方法中有效。如下的class C .....
public static void main(String[] args) { // TODO Auto-generated method stub class C { void funC() { System.out.println("funC"); } } C c = new C(); c.funC(); }
4. 匿名内部类
最常用的匿名内部类的
使用方式是需要创建某个接口类型(或者抽象类)的对象 ,如下,
如下String name, 匿名内部类访问局部变量时 必须用final修饰, 不然编译报错。
interface AA { abstract void funAA(); } public class Main { public static void main(String[] args) { // TODO Auto-generated method stub final String name = "hello" ; AA a = new AA() { public void funAA() { System.out.println(name); } }; a.funAA(); } }
5. 闭包和回调
闭包: 是一种能够被调用的对象,它保存了创建它的作用域的信息。
回调: 某个方法一旦获得内部类对象的引用后,就可以在适合时候反过来调用外部类的实例的方法。
如下例子中 interface Teachable 和 class Programer 都有work方法, 那如果一个人既是teacher 又是 programer怎么解决??
如果仅仅是 class TeachableProgramer extends Programer implements Teachable { ... }
那class TeachableProgramer中的work()到底是哪个的??
这则需要用闭包和回调,如下:
interface Teachable { void work(); } class Programer { String name; public Programer(){}; public Programer(String name) { this.name = name; } String getName() { return this.name; } public void work() { System.out.println("Programer coding"); } } class TeachableProgramer extends Programer { public TeachableProgramer(String name) { super(name); } private void teach() { System.out.println("Teacher teach"); } private class Colsure implements Teachable { public void work() { teach(); } } public Teachable getCallback() { return new Colsure(); } } public class Main { public static void main(String[] args) { TeachableProgramer people = new TeachableProgramer("kevin"); people.work(); people.getCallback().work(); } }
6. 枚举类
枚举类的创建用 enum 关键词, 如下两个例子创建枚举类
Gender1
public enum Gender1 { MALE, FEMALE; private String name; public void setName(String name) { switch (this) { case MALE: if(name.equals("man")) { this.name = name; } else { System.out.println("Error"); return; } break; case FEMALE: if(name.equals("woman")) { this.name = name; } else { System.out.println("Error"); return; } break; } } public String getName() { return this.name; } }
Gender2
public enum Gender2 { MALE("man"), FEMALE("woman"); private String name; private Gender2(String name) { this.name = name; } public String getName() { return this.name; } }
Gender3 枚举类实现接口
interface InterfaceXX { void fun1(); void fun2(); } public enum Gender3 implements InterfaceXX { MALE("man") { public void fun2() { System.out.println("fun2 in MALE"); } }, FEMALE("woman") { public void fun2() { System.out.println("fun2 in FEMALE"); } }; private String name; private Gender3(String name) { this.name = name; } public String getName() { return this.name; } public void fun1() { System.out.println("fun1 is the same in MALE and FEMALE"); } }
main 函数中使用枚举类
public class Main { public static void main(String[] args) { Gender1 g1 = Enum.valueOf(Gender1.class, "FEMALE"); g1.setName("man"); g1.setName("woman"); System.out.println(g1.getName()); Gender2 g2 = Enum.valueOf(Gender2.class, "MALE"); System.out.println(g2.getName()); System.out.println(Gender2.FEMALE.getName()); Gender3 g3 = Enum.valueOf(Gender3.class, "MALE"); System.out.println(g3.getName()); g3.fun1(); g3.fun2(); } }