内部类详解
4种内部类
内部类 | 位置 | 特点 |
---|---|---|
成员内部类 | 成员位置 | 无static修饰 、可以添加任意访问修饰符 |
静态内部类 | 成员位置 | 由static修饰、可以添加任意访问修饰符 |
局部内部类 | 局部位置(如方法) | 有类名、不能添加访问修饰符但是可以使用final修饰 |
匿名内部类 | 局部位置(如方法) | 无类名、不能添加访问修饰符但是可以使用final修饰 |
一、成员内部类
1、可访问外部类所有资源
如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
2、自身不能定义静态资源,因为其 实例化本身还依赖着外部类
3、外部类需要创建内部类对象来访问内部类资源
4、创建内部类对象的方式:
①在外部类内部创建
②在外部类外部创建
③在内部类内部使用隐藏的外部类对象(隐藏的this)
5、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
6、作用域:同其他的成员,为整个类体
代码示例:
package inner;
public class School {
//1
public int no = 1;
private String name = "**大学";
class Teacher{
//2
private String teacher_name = "张三";
private int no = 001;
public int id = 01;
public void print(){
System.out.println("我是"+name+"的老师"+teacher_name+",我的编号:"+no);//1
System.out.println(this.no+School.this.no);//③
School.this.use1();
}
}
public static void main(String[] args) {
School school = new School();
school.use1();
}
public void use1() {
System.out.println();
Teacher teacher = new Teacher();//①
teacher.print();
}
}
class OtherSchool{
School.Teacher teacher1 = new School().new Teacher();//②
}
二、静态内部类
1、可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问
2、外部类需要创建内部类对象来访问内部类资源
3、创建内部类对象的方式:
①在外部类内部创建
②在外部类外部创建
4、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
5、作用域:同其他的成员,为整个类体
代码示例:
public class School {
public int no = 1;
private String name = "**大学";
private static String name1 = "**大学1";
private static int no1 = 2;
static class Teacher{
private String teacher_name = "张三";
private int no = 001;
public int id = 01;
public void print(){
System.out.println("我是"+name1+"的老师"+teacher_name+",我的编号:"+no);//1
}
}
public void use1() {
System.out.println();
Teacher teacher = new Teacher();//①
teacher.print();
}
public static void main(String[] args) {
School school = new School();
school.use1();
}
}
class OtherSchool{
School.Teacher teacher1 = new School.Teacher();//②
}
三、局部内部类
1.可以直接访问外部类的所有成员,包含私有的。
如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
2.不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final,也不能被static修饰。
3.外部其他类不能访问局部内部类(因为局部内部类地位是一个局部变量)
4.外部类在方法中,可以创建 内部类 对象,然后调用方法即可
5.作用域:仅仅在定义它的方法或代码块中。
记住:
(1)局部内部类定义在方法中/代码块
(2)作用域在方法体或者代码块中
(3)本质仍然是一个类
代码示例:
public class School {
public int no = 1;
private String name = "**大学";
public void function(String str) {
/** 局部内部类Inner*/
class Inner {//2
private int no1 = 0;
private String name = "**大学1";
public void print() {
System.out.println(no);//1
System.out.println(name);
System.out.println(School.this.name);//1
System.out.print(str);
System.out.println("局部内部类...");
}
}
//4(在局部内部类上面定义会报错)
Inner inner = new Inner();
inner.print();
}
public static void main(String[] args) {
School school = new School();
school.function("我正在访问一个");
}
}
四、匿名内部类
1.匿名内部类的基本语法(必须实现一个接口或抽象类,没有构造方法)
new类或接口(参数列表){
类体
};
2.没有类名的内部类,不能使用class,extends和implements,没有构造方法。
3.可以直接访问外部类的所有成员,包含私有的。需要在匿名内部类内创建外部类对象进行访问(修改后,在外部类也不起作用);对于所处方法或代码块的变量,可以直接访问(但不能修改)。
如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员[在非静态函数里定义匿名内部类情况下])去访问
4.不能添加访问修饰符,因为它的地位就是一个局部变量
5.外部其他类不能访问匿名内部类
6.作用域:仅仅在定义它的方法或代码块中。
①匿名内部类的语法比较奇特,请大家注意,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,,因此可以调用匿名内部类方法。
7. 匿名内部类是局部内部类的特殊形式,所以局部内部类的所有限制对匿名内部类也有效。
代码示例:
interface Teacher {
String sayHello(String name);
void print();
}
public class School{
private int no = 1;
public final int id = 1;
private String name = "**大学";
public static void main(String[] args) {
//实现上面的接口创建了一个匿名内部类
final int i = 1;
int j = 19;
Teacher teacher = new Teacher() {
String name = "匿名内部类";
public void print(){
System.out.println(i);
System.out.println(j);
School school = new School();
System.out.println(school.no);
System.out.println(name);
}
public String sayHello(String name) { return "hello, " + name ; }
};
System.out.println(teacher.sayHello("leo"));
teacher.print();
}
}