所谓的内部类(Inner Class),顾名思义,就是将一个类定义在另外一个类的内部。一个类内部的类被称之为内部类。this
// Outer 为外部类,Inner 为内部类 public class Outer{ class Inner{ // ... } }
内部类间接实现多继承
示例:code
public class MultiExtends{ public static void main(String[] args){ C c = new C(); // 访问 A 类中的 showA() 方法 c.getInstanceA1(); // 访问 B 类中的 showB() 方法 c.getInstanceB1(); } } class A{ public void showA(){ System.out.println("A"); } } class B{ public void showB(){ System.out.println("B"); } } // 至关于同时继承了 A 类和 B 类 class C{ // 内部类 A1 private class A1 extends A{ public void showA(){ // 继承 A 类的 showA()方法 supper.showA(); } } // 内部类 B1 private class B1 extends B{ public void showB(){ // 继承 B 类的 showB()方法 supper.showB(); } } // 给外部提供访问内部私有类 A1 内的方法 的接口 public void getInstanceA1(){ new A1().showA(); } // 给外部提供访问内部私有类 B1 内的方法 的接口 public void getInstanceB1(){ new B1().showB(); } }
内部类实现父类与接口中的同名方法
示例:对象
public class MutilExtendsImplement{ public static void main(String[] args){ Son son = new Son(); // 访问抽象父类的 show() 方法 son.show(); // 访问接口中的 show() 方法 son.showSonInner(); } } // 抽象类 abstract class Parent{ // 抽象类中的 show() 抽象方法 public abstract void show(); } // 接口 interface IShow{ // 接口中的 show() 方法 // public void show(); public void show1(); } // 这种作法是不容许的,由于 Parent 类和 IShow() 存在同名方法 show(), Son 类不知道该实现哪一个 show() 方法 ,除非 抽象父类或者接口任一个修改方法名 // Son 类继承 Parent 类并实现 IShow 接口 class Son extends Parent implements IShow{ // 实现抽象父类 public void show(){ ... } // 接口中的方法名改成 show1() public void show1(){ ... } } // 若抽象父类和接口都不修改方法名,能够由内部类来实现 // 抽象类 abstract class Parent{ // 抽象类中的 show() 抽象方法 public abstract void show(); } // 接口 interface IShow{ // 接口中的 show() 方法 public void show(); } class Son extends Parent{ // 实现抽象父类的 show() 方法 public void show(){ System.out.println("抽象类中的 show() 方法"); } // 定义一个内部类来实现 IShow 接口 private class SonInner implements IShow{ // 实现接口的 show() 方法 public void show(){ System.out.println("接口中的 show() 方法"); } } // 提供给外部访问私有内部类 SonInner 方法的接口 public void showSonInner(){ new SonInner.show(); } }
成员内部类特色:继承
注:若成员内部类与外部类有同名方法或同名属性,成员内部类在访问外部类的同名方法或属性时要使用“外部类名.this.(外部)成员方法(属性)”形式,若成员内部类访问的是与外部内非同名的方法或属性,直接使用“方法名”或“属性名”访问便可接口
示例:作用域
public class MenberInnerClass{ // 程序主方法 public static void main(String[] args){ Outer outer = new Outer(); // 建立内部成员类实例 Outer.Inner innre = outer.new Inner(); } } // 外部类 Outer class Outer{ // 外部类属性 private String name; private int number; // 外部类方法 public void showOuter(){ System.out.println(name); System.out.println(number); // 外部类不能直接访问内部类的成员方法和属性 // System.out.println(number2); } // 内部类 Inner public class Inner{ private String name; private int number2; // 在成员内部类中不能声明静态的成员,包括属性和方法 // public static int number3 = 30; // 在成员内部类中能够声明静态的常量 private static final int number3 = 30; public void showInner(){ System.out.println(name); System.out.println(number2); // 内部类调用外部类成员 System.out.println(Outer.this.name); // 内部类调用外部类方法 Outer.this.showOuter(); } } }
静态内部类特色get
Outer.Inner inner = new Outer.Inner();
静态内部类有如下限制io
StaticInner.name
匿名内部类特色class
匿名内部类语法变量
new interface/superclass() {//类体}
示例:
public class AnonymousInnerClass{ public static void main(String[] args){ Person person = new Person(); // 利用匿名内部类实例化 Animail 的一个子类 person.feed(new Animial(){ // 实现抽象类中的抽象方法 eat() public void eat(){ System.out.println("eating"); } }); // 利用匿名内部类实现接口 Animail persion.feed(new Animail(){ public void move(){ System.out.println("moving"); } }); } } class Person{ // feed 方法传入 Animial 对象执行 eat() 方法 public void feed(Animail animail){ animail.eat(); } } // 抽象父类 Animail abstract class Animail{ // 抽象方法 eat() public abstract void eat(); } // 接口 Animail interface Animail{ public void move(); }
局部内部类特色
局部内部类有如下限制
示例:
public class LocalInnerClass{ public static void main(String[] args){ Outer outer = new Outer(); // 经过调用 Outer 的 showOuter() 方法来调用局部内部类 Inner outer.showOuter(); } } class Outer{ private String name = "tom"; private int num1 = 10; public void showOuter(){ // 局部变量 int num2 = 20; // 局部内部类 Inner,定义在 showOuter() 方法中 class Inner{ private String name = "jack"; private int num3 = 30; public void showInner(){ System.out.println(name); System.out.println(num3); } } // 构造局部内部类的实例,只能在当前这个方法的做用域内构造 Inner inner = new Inner(); inner.showInner(); } }