1、基本概念
内部类:定义在一个类的内部进行其他类结构的嵌套操作。虽然内部类破坏了程序的结构,但是内部类也可以方便的操作外部类的私有访问。
2、内部类为什么存在?
1)内部类方法可以访问该类定义所在作用域中的数据,包括被private修饰的私有数据
2)内部类可以对同一个包中的其它类隐藏起来
3)内部类可以实现单线程的缺陷
4)当我们想要定义一个回调函数却不想写大量代码的时候,可以选择用匿名内部类来实现
使用内部类实现多继承:
class A{
private String name = "A的私有属性";
public String getName(){
return name;
}
}
class B{
private int age = 20;
public int getAge(){
return age;
}
}
class Outter{
private class InnerClassA extends A{
public String name(){
return super.getName();
}
}
private class InnerClassB extends B{
public int age(){
return super.getAge();
}
}
public String name(){
return new InnerClassA().name();
}
public int age(){
return new InnerClassB().age();
}
}
public class Test{
public static void main(String[] args) {
Outter outter = new Outter();
System.out.println(outter.name());
System.out.println(outter.age());
}
}
3、内部类与外部类的关系
- 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
- 内部类是一个相对独立的实体,与外部类不是is-a关系
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素
- 外部类可以通过内部类引用间接访问内部类元素
内部类直接访问外部类的元素:
class Outter{
private String outName;
private int outAge;
class Inner{
private int InnerAge;
public Inner(){
Outter.this.outName = "I am Outter class";
Outter.this.outAge = 20;
}
public void display(){
System.out.println(outName);
System.out.println(outAge);
}
}
}
public class Test{
public static void main(String[] args) {
Outter.Inner inner = new Outter().new Inner();
inner.display();
}
}
外部类通过内部类引用间接访问内部类元素:
class Outter{
public void display(){
Inner inner = new Inner();
inner.display();
}
class Inner{
public void display(){
System.out.println("I am InnerClass");
}
}
}
public class Test{
public static void main(String[] args) {
Outter outter = new Outter();
outter.display();
}
}
4、内部类分类
1)在外部类外部创建内部类
Outter.Inner in = new Outter().new Inner();
2)在外部类内部创建内部类Inner in = new Inner();
4.1 成员内部类
- 成员内部类中不能有任何static的变量和方法
- 成员内部类是依附于外围类的,所以只有先创建了外围类才能创建内部类
4.2 静态内部类
概念:
static关键字可以修饰成员变量、方法、代码块,也可以修饰内部类,使用static修饰的内部类就是静态内部类。
外部类创建语法:
外部类.内部类 内部类对象 = new 外部类.内部类();
静态内部类和非静态内部类的区别:
非静态内部类在编译完成之后会隐含地保存一个引用,这个引用是指向创建它的外围类,但是静态内部类却没有这个引用。
静态内部类特点:
- 静态内部类的创建不依靠外围类,可以直接创建
- 静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类都可以(因为外围类的非static变量和方法必须创建外围类对象,而静态内部类不需要创建外围类就可以直接使用)
4.3 方法内部类
概念:
方法内部类(局部内部类),定义在外部类的方法中,局部内部类和成员内部类基本一致,只是作用域不同,方法内部类只能在该方法中使用,出了该方法就会失效。
方法内部类特点:
- 方法内部类不允许使用访问权限修饰符,public private protected都不允许
- 方法内部类对外完全隐藏,除了创建这个类的方法可以访问它,其它地方不允许访问
- 方法内部类要想使用方法形参,该形参必须使用final声明(JDK1.8形参变为隐式final声明)
class Outter{
private int num;
public void display(final int test){
class Inner{
private void fun(){
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
public class Test{
public static void main(String[] args) {
Outter outter = new Outter();
outter.display(20);
}
}
4.4 匿名内部类
概念:
匿名内部类其实就是一个没有名字的方法内部类,它符合方法内部类的所有约束。
匿名内部类特点:
- 匿名内部类没有访问修饰符
- 匿名内部类必须继承一个抽象类或实现一个接口
- 匿名内部类中不能存在任何静态成员或方法
- 匿名内部类没有构造方法,因为它没有类名
- 与方法内部类相同,匿名内部类也可以引用方法形参,此形参也必须声明为final
interface MyInterface {
void test();
}
class Outter {
private int num;
public void display(final int para) {
//匿名内部类,实现了MyInterface接口
new MyInterface() {
public void test() {
System.out.println("匿名内部类" + para);
}
}.test();
}
}
public class Test {
public static void main(String[] args) {
Outter outter = new Outter();
outter.display(20);
}
}
总结:(内部类特点)
1)内部类破坏了程序的结构
2)方便进行私有属性的访问(外部类也可以访问内部类的私有域)
3)如果发现类名称上出现了.
,应立即想到内部类的概念