(一)内部类定义
如果一个类A定义在另外一个类B中,这个类A称为外层类B的成员内部类。比如:
public void A{
private void B{};//B为A的内部类
}
(二)内部类与外部类及外围类的关系
1、内部类不仅可以访问而且可以操作外层类的private成员变量(比如赋值),而外围类不能直接直接访问内部类的成员变量,必须通过
内部类对象引用才能调用;外部类也不能访问其它类的private成员变量的,除非其它类提供了非private的方法来访问这些成员变量。
public void A{
priave int a;
private void B{
private int a;
public A get(){
return A.this;//对外层类引用
}
public void set(int a){
this.a = a;//内部类成员变量及方法参数变量
A.this.a = this.a;//外层及内部类成员变量
}
};//B为A的内部类
}
2、内部类可以调用外层类的方法,如果内部类有同名方法必须使用"OuterClass.this.MethodName()"格式调用(其中OuterClass与
MethodName换成实际外部类名及其方法;this为关键字,表示对外部类的引用);若内部类无同名方法可以直接调用。而外围类无法直接
调用内部类的private方法,外部类同样无法直接调用其它类的private方法。注意:内部类直接使用外部类的方法与该方法的权限与是否
static无关,它取决于内部类是否有同名方法。
//内部类对外围类的成员方法调用的一般方法事例
public class OuterClass {
private static void outerMethod() {
System.out.println("It's Method of OuterClass");
}
class Innerclass {
public void innerMethod() {
OuterClass.this.outerMethod();//内部类成员方法与外部类成员方法同名时,使用this调用
outerMethod();//内部类没有同名方法时执行外部类的方法
}
}
public static void main(String[] args) {
OuterClass t = new OuterClass();
OuterClass.Innerclass in = t.new Innerclass();
in.innerMethod();
}
}
(三)内部类的实例化
内部类实例化不同于普通类,普通类可以在任意需要的时候实例化,而内部类必须在外层类实例化以后方可实例化,并与外层类建立关系
。
假设B是A的内部类,methodC是类A的一个方法,可以通过以下两种途径实现B的实例化:
一是在其它外部类或main()中实例化,声明和初始都要明确与外层类及引用对象的关系:
A a = new A();
A.B b = a.new B();
二是在A内部方法内实例化,实例化时java自动把它与外层类引用对象联系起来:
void method(){
B b = new B();
}
另外,内部类如果定义为静态类(static class),在实例化时不需要对外部类实例化:
public class StaticCls{
public static void main(String[] args){
OuterCls.InnerCls oi=new OuterCls.InnerCls(); //
}
}
class OuterCls{
public static class InnerCls{ //内定类定义为静态类
InnerCls(){
System.out.println("InnerCls";
}
}
}
(四)什么情况下使用内部类
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外层类的对象。所以你可以认为内部类提供了某种进
入其外层类的窗口。
使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外层类是否已经继承了某个(接口的)实
现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角
度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
(五)完整实例
public class Test2 {
private int num;
public Test2() {
}
public Test2(int num) {
this.num = num;
}
public Test2 getTest2(int num) {//当方法代码较多时,可以声明一个内部类,把代码转移到内部类的方法里,以达到结构清
晰的目的
Inner inner = new Inner();
return inner.getTest2(1);
}
private class Inner {
private int num;
public Test2 getTest2(int num) {
this.num = num;//注意区别内部类成员变量与形参变量
Test2.this.num=this.num+1;//区别外层类与内部类的成员变量
System.out.println("value of num is class-Inner's member variable: " + this.num);
return Test2.this;//通过this调用外围类的对象
}
public Test2 newTest2() {
// Test2.this.getTest2(1);//调用外层类Test2的getTest2方法
return new Test2();
}
}
public static void main(String[] args) {
Test2 test = new Test2(5);
Test2.Inner inner = test.new Inner();
// Test2 test2 = test.getTest2(2);//通过Test2的方法创建内部类并使用
Test2 test2 = inner.getTest2(2);
Test2 test3 = inner.newTest2();
System.out.println("Value of num is Test2's member variable and has been modified :" + test2.num);
System.out.println("Value of num ,object of Test2 is created newly: " + test3.num);
}
}
(六)补充材料:内部类如何调用外部类的实例
import java.util.LinkedList;
import java.util.List;
public class test1 {
private List listeners = new LinkedList();
public void addListeners(IListener listener) {
this.listeners.add(listener);
}
private test1 outer = this; // 把外部类引用赋值给成员变量
private class InnterClass {
public void publish() {
// 将事件发布出去 (2)
for (int i = 0; i < listeners.size(); i++) {
IListener listener = (IListener) listeners.get(i);
listener.receiveEvent(outer);// 内部类通过外部类成员变量调用外部类
}
}
}
public static void main(String[] args) {
test1 out = new test1();
test1.InnterClass in = out.new InnterClass();
in.publish();
}
}
interface IListener {
public void receiveEvent(test1 obj);
}