指的是Java中可以将一个类定义在另一个类的内部
内部类可以定义在 类的内部(与类成员层次一致)
内部类可以定义在 方法/块内部(与类成员相差一个层次 与方法的局部变量一个层次)
1.成员内部类
1)内部类存在后,编译之后会生成两个class文件:OuterDemo.class 和 OuterDemo$InnerDemo.class
将一个类直接定义在类的里面 作为成员与属性或方法层次一致
2)可以与正常类一样 使用不同的修饰符修饰
3)若想要在内部类中通过对象调用外部类成员 需要 类名.this.外部类成员
4)若想要使用内部类的属性和方法 必须创建对象 通过外部类对象操作
5)成员内部类不能有static修饰的变量和方法 但是可以定义final
好处:
1.可以省略一个.java文件
2.成员内部类中可以访问到外部类中的所有成员 包括私有的
2.局部内部类(不太常用)
将一个类定义在方法/块里面 作为成员的内部结构 与临时的局部变量一个层次
局部内部类像是一个局部变量一样 不能用public proctected private及static等修饰,只能用abstract或final修饰
(因为这些都是修饰类和成员的,不能修饰局部变量,普通方法中不能定义static内部类)
在不同的方法中可以定义重名的局部内部类
局部内部类命名规则Demo$1InnerTestMethod Demo$2InnerTestMethod(局部内部类重名的情况下)
局部内部类可以访问外部类成员 局部内部类也能访问局部变量
局部内部类的局部变量需要加final修饰,如果不写默认也是这个
(因为类编译时会出现个类模板 类模板在编译加载时变量里的值是固定的 类加载好后里面存一个值 把变量值改后 类编译又得到另一个值 和原来的值对不上)
3.匿名内部类(常见)
成员匿名内部类
局部匿名内部类
public interface Test{
publicvoid test();
}
public class Son implements Test{
public void test(){
}
}
public static void main(String[] args){
Test t = new Test(){//因为接口不能创建对象 所以这个new的是Test接口的子类 子类中的方法就可以省略了
public void test(){
}
};
}
即(把中间子类继承的过程省略了)
public interface Test{
public void test();
}
public static void main(String[] args){
Test t = new Test(){
public void test(){
}
};
}
通常接口或抽象类的具体子类这样写
开发中为了省略一个类文件 上述写法比较常见
匿名内部类比较特殊 只有类体 没有类的所有结构(修饰符 名字 继承 实现都没有)
所以 匿名类不能用任何修饰符修饰 匿名内部类也没有构造方法
4.静态内部类
成员静态内部类
只能在类中定义 作为类的成员
静态内部类不需要外部类对象操作 通过正常的方法就可以直接创建内部类对象(因为静态成员在对象创建前就已经存在 即类加载时就已经有了)
静态成员不能访问非静态成员(自己类和外部类都不行)
静态内部类可以访问的是外部类的静态成员
package test_innerclass;import sun.security.mscapi.CPublicKey;public class Demo {private String name = "这是外部类的普通属性";private static String name1 = "这是外部类的静态属性";public static void testDemo(){System.out.println("这是外部类的静态方法");}public void testInnerMethod(){//局部内部类 写在方法或者块里//只是临时存在 方法执行完就被回收了String myName = "局部外部类的属性";class InnerTestMethod{String myName = name;public void getName(){System.out.println(myName+name);}}}//成员内部类public class InnerDemo{private String name = "这是内部类的属性";public void testInnerDemo(){System.out.println("这是内部类的方法,"+Demo.this.name);//当属性同名时 要想在这里调用外部类的属性 可以用Demo.this.name//如果只写name 会根据就近原则 调用的是内部类的属性//不同名的话可以直接写属性名即可//调用内部类的属性只需要this.nametestDemo();//可以直接调用外部类的方法}}//静态内部类public static class StaticInnerDemo{private String staticName = "这是静态内部类的属性";public void testStaticInnerDemo(){System.out.println("这是静态内部类的方法,"+staticName+","+name1);//因为是 静态的 所以它不能访问外部非静态的成员Demo.testDemo();//静态内部类只能访问外部类中的静态成员 非静态的无法访问}}}
主方法:
package test_innerclass;import test_innerclass.Demo.InnerDemo;import test_innerclass.Demo.StaticInnerDemo;public class RunMain {public static void main(String[] args){//创建内部类对象InnerDemo innerDemo = new Demo().new InnerDemo();//导包后可以这样写//要是没有导包可以这样写// Demo demo = new Demo();// Demo.InnerDemo innerDemo = demo.new InnerDemo();//也可以直接// Demo.InnerDemo innerDemo = new Demo().new InnerDemo();innerDemo.testInnerDemo();//调用成员内部类方法//创建静态内部类对象Demo.StaticInnerDemo sid = new Demo.StaticInnerDemo();//没导包需要这样写//StaticInnerDemo sid = new StaticInnerDemo();//导包后可以这样写sid.testStaticInnerDemo();//调用静态内部类方法Outter.StaticInner si = new Outter.StaticInner();应该这样看 Outter.StaticInner si = new [Outter.StaticInner]();将Outter.StaticInner作为一个整体,所以说静态内部类不依赖于外部类的对象}}
