**内部类:**类/接口里定义类
- 方法内部类
- 成员内部类
- 静态内部类----static 修饰的类一定是静态内部类
- 匿名内部类
方法内部类:
- 在方法的内部进行定义
- 可以定义所有非静态的信息以及静态常量—方法在对象调用的时候使用。常量一般放在常量池中,不是在静态区
- 可以定义构造代码块,但是不能定义静态代码块,静态信息都是随着类的加载而加载,顺序对不上
- 可以正常的继承和实现
5. 不能被访问权限修饰符修饰(public…),但是可以用abstract以及final修饰 - 可以获取外部类的所有的信息,包括私有化信息
- **只能获取本方法中的常量,**方法中的如果有内部类的存在,那么在这个方法中定义的属性都是常量属性,不可变属性
- int y=2;//jdk1.8之前,需要手动给常量加final常量,在jdk1.8及其以后底层默认添加final常量,如果手动添加,则底层不在进行添加
- 方法只有被调用的时候能够确定对象的属性
- 可以定义构造方法,进行自我属性的初始化
- 可以有重载的方法,进行方法的不同实现
- 使用方法内部类的时候必须让对象的创建在类的后面,方法的里面,否则解析不到
- 内部类和外部类是两个互相的类,对于方法的中的属性的访问是在各自的常量池中进行访问
public class InnerDemo1 {
public static void main(String[] args) {
new Outter1().m();
}
}
//外部类
class Outter1 {
//属性
static int k=1;
//方法
public void m(){
int y=2;//jdk1.8之前,需要手动给常量加final常量
//在jdk1.8及其以后底层默认添加final常量,如果手动添加,则底层不在进行添加
//方法内部类
class Inner1 extends Object implements Cloneable{
//可以定义所有非静态的信息以及静态常量
//可以正常的继承和实现
//不能被访问权限修饰符修饰(public...),但是可以用abstract以及final修饰
//可以获取外部类的所有的信息,包括私有化信息
//只能获取本方法中的常量
static final int x=1;
public void n(){
System.out.println(k);
System.out.println(y);
}
}
//方法内部类必须要卸载方法的内部,内部类的后面
Inner1 inner1 = new Inner1();//symbol符号的resolve解析,解决的意思
inner1.n();
}
}
成员内部类:
1**. 类似于作为类的成员变量存在**
2. 可以定义所有的非静态信息以及静态常量
3. 可以定义构造方法和重载方法,能够被继承和实现
4. 该类和类的加载一起,class字节码文件是一样的要被加载和转换
5. 可以正常的继承和实现
6. 可以让访问权限修饰符(public…)以及abstract,final来修饰
7. 可以获取外部类的所有信息,静态信息,非静态信息
8. 外部类的属性是可以变化的,可以定义为基本数据类型和引用数据类型
public class InnerDemo2 {
public static void main(String[] args) {
//获取内部类,将成员内部类看做是外部类的一个属性
//Outer2.Inner2 inner2=new Outer2().in2;//
//in2=new Outer2.Inner2();
Outer2.Inner2 inner21=new Outer2().new Inner2();
}
}
//外部类
class Outer2{
//属性,静态变量被所有对象所共享
static int k;
//非静态属性
//Inner2 in2=new Inner2();
//成员内部类
//可以定义所有的非静态信息以及静态常量
//可以正常的继承和实现
//可以让访问权限修饰符(public....)以及abstract,final来修饰
//可以获取外部类的所有信息
public class Inner2 extends Object implements Cloneable{
static final int x=1;
public void n(){
System.out.println(k++);
m();
}
}
//方法
public void m(){}
}
```
**静态内部类:**---**只有成员内部类才能被定义为静态内部类**
1. 成员内部类被static来修饰称为静态内部类---->**可以类比于成员的静态变量**
2. 可以定义所有信息,静态信息和非静态信息都可以
3. 可以正常的继承和实现
4. 可以被访问权限修饰符以及abstract,final进行修饰
5. 只能获取外部类的静态信息---自己本身是静态区的东西,所以只能访问非静态的东西
6. **static修饰class的一定是内部类**
7. **可以有构造方法和重载方法--->进行成员变量的初始化信息**
因为静态内部类是被static修饰,所以可以通过类名来访问或者调用静态资源
```html
//创建静态内部类对象
Outer3.Inner3 inner3=new Outer3.Inner3();
System.out.println(inner3.x);
```**
**匿名内部类:**--->
1. 用于继承类/实现接口,重写抽象方法
2. 可以被继承的类/接口都可以拥有匿名内部类的形式
3. 匿名内部类只能使用一次
4. 当做参数传递时使用
5. 匿名内部类不能定义任何静态成员,方法。
6. 匿名内部类必须实现接口或抽象父类的所有所有抽象方法
7. 匿名内部类中的方法不能是抽象的
8. 你们内部类访问的外部类成员变量或者方法必须用static修饰
9. 匿名内部类会继承一个父类(有且只有一个)或实现一个接口(有且只有一个),实现父类或接口中所有抽象方法,可以改写父类中的方法,添加自定义方法。
10. 当匿名内部类和外部类有同名变量(方法)时,默认访问的是匿名内部类的变量(方法),要访问外部类的变量(方法)则需要加上外部类的类名。
11. 匿名内部类因为没有类名,可知匿名内部类不能定义构造器。
12. 可以获取外部的非静态属性的信息.
```html
//匿名内部类
public class InnerDemo4 {
public static void main(String[] args) {
//创建抽象类子类对象
/* D d=new D();
d.m();*/
//继承抽象类-->重写抽象方法--->创建匿名内部类对象(就是抽象类的声明对象)
//当类可以被继承/接口时,可以拥有匿名内部类的形式
C c=new C() {
@Override
public void m() {
//static int i;
System.out.println(1);
}
};
c.m();
//普通类也具有匿名内部类的形式
//接口也具有匿名内部类的形式
//调用方法
//匿名内部类当做参数使用
B b=new B(){};
A a=new A() {
};
m(new A(){});//当做参数进行传递
}
public static void m(A a){}
}
//接口
interface A{
int i=0;
}
//普通类
class B{}
//抽象类
abstract class C{
public abstract void m();
}
class D extends C{
@Override
public void m() {
System.out.println(1);
}
}
```
**接口里面定义类/内部接口默认都是被static修饰**
原因如下:**接口的本质本身不是类,而是一种规范,不具有类的初始化的信息的特点**
**需JVM在一开始就直接给了初始化信息,而满足这个特性的只有static的关键字保证类的加载结束前能初始化结束,而且里面的信息都是使用final进行修饰的**