意义

为了更好的封装

分类

Nested Classes(嵌套类)

被static 修饰的成员内部类

inner Classes(内部类)

实例内部类

没有static修饰的成员内部类
除了常量外不能用static修饰字段

Local Class局部类

在宿主类类体括号内部某个局部区域中声明的内部类
除了常量外不能用static修饰字段

Anonymous Classes(匿名类)

不能显示指定类名
不能显示声明构造方法,但是创建匿名类的实例时的确会调用父类的指定构造方法
除了常量外不能用static修饰字段

声明

Nested Classes(嵌套类)

public class Computer{
static class Brand{
}
}

实例内部类

public class Computer{
class Mainboard{
}
}

局部内部类

public class Computer{
public void show(){
class Printer{
}
}
}

匿名内部类

Object o=new Object(){
}

字节码文件的名称

嵌套类对应的字节码文件名称时外部类名$内部类类名.class
局部内部类对应的字节码文件名称时外部类类名$n(n位数字表示第几次出现)内部类类名.class
匿名内部类对应的字节码文件名称时外部类类名$n .class

声明内部类型变量

对于嵌套类来说,使用外部类名.内部类名来指定变量类型 如:Computer.Brand brand=null;
对于局部类来说,只能在其作用域内部直接使用其类名来声明
因为不能显式指定匿名类的类名,所以也就不能声明匿名类型的引用变量,
但是可以声明匿名类所实现的接口类型的引用变量或匿名类所继承父类类型的引用变量

创建内部类实例

静态内部类(嵌套类)

使用new 外部类类名.内部类类名(参数)形式来创建实例
不如 Computer.Brand b=new Computer.Brand();

实力内部类

首先需要创建外部类类型的实例 比如:Computer c =new Computer();
然后再在外部类的实例的基础上为来创建实例内部类的实例Computer.Mainbpard m =c.new Mainbpard();

局部类

直接在其有效作用域中使用new 关键字创建即可

匿名内部类

创建实现了某个接口的匿名类的实例

此时匿名类的直接父类是Object类
此时匿名类实现了指定的接口(单个)
public interface Flyable
void fly();
}

f = new Flyable() { // 匿名类开始 【魂】
@Override
public void fly() { // 在匿名类中实现 Flyable 接口中所有的抽象方法
System.out.println( “飞飞飞,在梦里飞,想飞哪里飞哪里” );
}
}; // 匿名类结束
f.fly();

创建了实现了某个抽象类并实现其中所有的抽象方法的匿名类的实例

public abstract class Human {
public String name ;
public Human() {
super();
System.out.println( “Human()” );
}
public Human( String name ) {
super();
this.name = name ;
System.out.println( “Human( String )” );
}

  1. **public** **abstract** **void** **eat**( **String** food );<br />}
  • 创建继承了某个抽象类并实现其中所有抽象方法的匿名类的实例
    /
    public class AnonymousClassTest2 {
    public static void main(*String
    [] args) {

    1. **Human** h = **null** ;
    2. // h = new Human( "张三丰" ); // 抽象类有构造方法,但是抽象类不能实例化
    3. // 形式上,似乎是在通过 new 关键字 创建抽象类 Human 的实例 【尸体】<br /> // 本质上,创建一个继承了 Human 类 并实现了其中所有抽象方法的 匿名类 的实例 【借尸还魂】<br /> h = **new** **Human**( "张三丰" ) { // 匿名类开始 【魂】<br /> @Override<br /> **public** **void** **eat**(**String** food) {<br /> **System**.out.println( **this**.name + "吃" + food );<br /> }<br /> }** ;** // 匿名类结束
    4. h.eat( "西瓜" );
    5. **System**.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
    6. h = **new** **Human**() {<br /> @Override<br /> **public** **void** **eat**(**String** food) {<br /> **System**.out.println( **this**.name + "吃" + food );<br /> }<br /> };<br /> h.name = "张君宝" ;<br /> h.eat( "冬瓜" );

创建继承某个具体类的匿名类的实例

匿名类的直接父类就是相应的具体类
可以在匿名类中重写被继承类中的某些方法(根据需求来确定)
在创建匿名类实例时可以调用父类中带参数的构造方法
public class Aircraft {
public String type ;
public Aircraft(){
super();
}
public Aircraft( String type ){
super();
this.type = type ;
}
public void fly() {
System.out.println( “飞行中…” );
}
public void travel() {
System.out.println( “行驶中…” );
}
}


public class AnonymousClassTest3 {
public static void main(String[] args) {
Aircraft a = new Aircraft();
a.fly();
a.travel();
System.out.println( “~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~” );

  1. **Aircraft** b = **new** **Aircraft**() { } ; // 父类引用 指向 子类对象 ( 因为最后的 { } 就是一个匿名类的类体 )<br /> **System**.out.println( b.getClass() );
  2. **System**.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
  3. // 调用 父类无参数构造方法<br /> **Aircraft** c = **new** **Aircraft**() {<br /> // 在匿名类中声明实例变量<br /> **String** name = "航天飞机" ;<br /> @Override<br /> **public** **void** **fly**() { // 重写从父类 中继承的 fly 方法<br /> **System**.out.println( **this**.name + "正在飞行" );<br /> }<br /> } ;
  4. c.fly(); // 调用重写后的方法
  5. **System**.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
  6. // 调用 父类有参数构造方法<br /> **Aircraft** d = **new** **Aircraft**( "飞船" ) {<br /> // 在匿名类中声明实例变量<br /> **String** name = "嫦娥二号" ;<br /> @Override<br /> **public** **void** **fly**() { // 重写从父类 中继承的 fly 方法<br /> **System**.out.println( **this**.name + **this**.type + "正在月球上空飞行" );<br /> }<br /> } ;
  7. d.fly(); // 调用重写后的方法