类的编码规则:
1. 一个.java文件中可以有很多类
2. public权限的类最多只能有一个 ,.java文件的文件名必须是public类的全名
3. 如果没有public类, 那么文件名可以随便命名
4. 将一个类定义在另一个类里面, 这样的类就称为内部类
5. javac编译.java文件的时候 , 会为每个类生成一个.class文件
6. 内部类的文件名形式为Outer$Inner1.class
1. 成员内部类: 下面的代码定义了一个成员内部类
public class Outer {
privateInteger num= 0;
private class Inner1 {
privateInteger num= 1;
public void print() {
System.out.println("inner1 print outer's num = "+ Outer.this.num);
}
}
protected classInner2 {
privateInteger num= 2;
public void print() {
System.out.println("inner2 print outer's num = "+ Outer.this.num);
}
}
public voidprint() {
System.out.println("outer print inner1's num1 = "+ new Inner1().num);
System.out.println("outer print inner2's num2 = "+ new Inner2().num);
}
public staticvoidmain(String[] args) {
Outer outer = new Outer();
outer.newInner1().print();
outer.print();
outer.newInner2().print();
}
}
代码分析:
- 内部类可以用protected和private关键字来进行修饰
- 在内部类的print()方法中, 我们可以看到成员内部类可以任意访问外部类的私有变量和方法
- 成员内部类拥有和外部类拥有同名的变量num和方法print(), 我们在内部类中通过Outer.this.num来调用外部类的同名变量和同名方法
- 外部类调用成员内部类的变量num和方法print()的时候需要先实例化一个内部类的对象newInner1()才能调用
- 成员内部类的实例化操作,要先实例化外部类Outerouter = new Outer();, 然后通过outer对象实例化一个内部类outer.newInner1()
2.静态内部类:
public class Outer {
private staticInteger count= 0;
public void print() {
System.out.println("outer print inner3 count = "+ new Inner3().count);
}
public staticclassInner3 {
privateInteger count= 3;
public void print() {
System.out.println("inner2 print outer's num = "+ Outer.count);
}
}
public staticvoidmain(String[] args) {
Outer outer = new Outer();
Outer.Inner3inner3 =new Outer.Inner3();
inner3.print();
outer.print();
}
}
代码分析:
1. 静态内部类比成员内部类多了一个static修饰符
2. 静态内部类不依赖于外部类来进行实例化
3. 静态类不能使用外部类的非static变量 , 要使用的话只能通过实例化一个外部类变量来使用
3. 局部内部类
public class Outer {
privateInteger count= 0;
public void print() {
classInner4 extendsOuter {
privateInteger num= 4;
public String str() {
return this.num.toString();
}
}
System.out.println("outer print inner4's num = "+ new Inner4().str());
}
public staticvoidmain(String[] args) {
newOuter().print();
}
}
局部内部类是定义在一个方法中或者一个代码块里面的类 , 作用域就在定义该内部类的方法中或者代码块
局部内部类不能有public、protected、private以及static修饰符
4.匿名内部类:
public abstract class AbstractOuter {
public abstractInteger count();
}
public class Outer {
public staticvoidprint(AbstractOuter outer) {
intcount = 10;
System.out.println("outer print count = "+ outer.count(count));
}
public staticvoidmain(String[] args) {
inttoAdd = 10;
print(newAbstractOuter() {
@Override
publicInteger count(intcount) {
returncount + toAdd;
}
});
}
}
代码分析:
1. 一个抽象类或者接口是没有办法直接new的,我们必须要先有实现类才能new出来它的实现类实例。
2. 所以在mian方法中直接使用匿名内部类来创建一个AbstractOuter实例。
3. JDK1.8之前, 内部类要想访问方法中的参数toAdd, 参数toAdd必须要用final修饰符, 在JDK1.8中可以不加final