内部类的基础知识
1.定义:在一个类中进行其他类结构的嵌套
class Outer{ private String msg = "Hello World" ;
// ********************************
class Inner{ //定义一个内部类
public void print(){ //定义一个普通方法
System.out.println(msg); //调用msg属性
}
}
// ********************************
//在外部类中定义一个方法,该方法负责产生内部类对象并且调用print()方法
public void fun(){
Inner in = new Inner(); //内部类对象
in.print(); // 内部类提供的print()方法
}
}
public class Test{
public static void main(String[] args) {
Outer out = new Outer(); //外部类对象
out.fun(); //外部类方法 }
}
2.内部类的优点
a.内部类和外部类可以访问彼此的私有域
b。内部类可以实现java的单继承局限
c。内部类可以对同一包中的其他类隐藏起来,仅供外部类使用(保护性)
缺点:结构复杂
3.内部类和外部类的关系
a。对于非静态内部类而言,内部类的创建需要依赖外部类的实例化对象,在没有外部类对象之前是无法创建内部类的;
b.内部类是一个相对独立的个体,与外部类不是is-a关系
c。内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问,包括内部类的私有属性,直接用对象.属性名调用,不用用getter和setter方法
4.创建内部类对象(在外部类之外)
a。创建非静态内部类对象---------》依靠外部类对象存在
外部类.内部类 内部类引用=new 外部类().new内部类();
eg:Outer.Inner in=new Outer().new Inner();
//Outer.this表示当前外部类的对象,在内部类调用外部类的属性或者方法时,会隐
式调用Outer.Inner;
b.创建静态内部类----->不依靠外部类对象存在
外部类.内部类 内部类引用=new 外部类.内部类();
eg:Outer.Inner in=new Outer.Inner();-----》表示没有调用外部类的构造方法,所以没
有创建外部类对象;
5.成员内部类-类比成员方法
a.成员内部类不能定义任何static变量或方法,可以访问外部类的静态域,但不能 定义;
b.成员内部类要依附外部类new.Outer().new Inner();
c. 内部类可以被private修饰,私有内部类,表示只能被外部类使用(HaspMap中的Entry内部类)
class Outer{ //先定义一个外部类
private String msg = "Hello World" ;
// ********************************
class Inner{ //定义一个内部类
public void print(){ //定义一个普通方法
System.out.println(msg); //调用msg属性
}
}
6.静态内部类-类比静态方法 —》static所修饰的内部类
a.静态内部类的创建不需要外部类,可以直接创建
b.静态内部类不可以访问外部类的任何非static域,但是可以自己定义非静态属性
class Outer{
private static String msg = "Hello World" ;
// ********************************
static class Inner{ //定义一个内部类
public void print(){ //此时只能使用外部类中的static操作
System.out.println(msg); //调用msg属性
}
}
// ********************************
//在外部类中定义一个方法,该方法负责产生内部类对象并且调用print()方法
public void fun(){
Inner in = new Inner(); //内部类对象
in.print(); // 内部类提供的print()方法
}
}
7.方法内部类–》定义在方法中的成员内部类,所以包含成员内部类的所有属性
a.方法内部类不能使用任何访问权限修饰符,public,private,protected均不允许
b。方法内部类对外(方法外)完全隐藏,除了该方法可以访问它之外,其余地方均不能访问
c。方法内部类想要使用方法形参【方法中的参数列表中就被隐式声明了】,该形参必须使用final声明(JDK8变为隐式final)
d。方法内部类还是可以直接访问外部类的所有属性【包括静态和非静态的属性,不用通过对象调用】
e。可以访问外部类的静态属性,但是不能自己定义静态属性
class Outter {
private int num;
public void display(int test) {
class Inner {
private void fun() {
num++;
System.out.println(num);
System.out.println(test);
}
}new Inner().fun();
}
}
8.匿名内部类
a. 匿名内部类是没有访问修饰符的。
b. 匿名内部类必须继承一个抽象类或者实现一个接口
c. 匿名内部类中不能存在任何静态成员或方法,但是可以访问外部类的静态属性和静态方法
d. 匿名内部类是没有构造方法的,因为它没有类名。
e. 与局部内部相同匿名内部类也可以引用方法形参。此形参也必须声明为 final
// 匿名内部类,实现了MyInterface接口
new MyInterface(){
@Override
public void test() {
System.out.println("匿名内部类"+para);
}
}.test();
9.一个面试问题
成员内部类是否能够定义静态成员属性?
答:不可以直接定义静态属性, public static a=10,不能再成员内部类中定义;
被final所修饰的值在编译期间就被确定下来,不依靠对象而存在所以 pubulic statiic final int A=10,可以存在;