内部类基本介绍
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class).嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员[属性、方法、构造器、代码块、内部类]内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系
基本语法
class Outer{ //外部类
class Inner{ //内部类
}
}
class Other{ //外部其他类
}
内部类的分类
定义在外部类局部位置上:
(1)局部内部类
(2)匿名内部类
定义在外部类的成员位置上:
(1)成员内部类(没用static修饰)
(2)静态内部类(使用static修饰)
局部内部类(定义在外部类的位置)
(1)可以直接访问外部类的所有成员,包含私有的
(2)不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量不能使用修饰符。但是可以使用final修饰
(3)作用域:仅仅在定义它的方法或代码块中
(4)局部内部类访问外部类的成员 :直接访问
(5)外部类访问局部内部类成员 :创建对象,再访问(必须在作用域内)
(6)外部其它类不能访问局部内部类(因为局部内部类的地位就是一个局部变量)
(7)如果外部类和内部类的成员重名,遵守就近原则,可以通过(外部类名.this.成员)来访问外部类成员
package com.innerclass;
public class LocalInnerClass {
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
outer02.m1();
}
}
class Outer02{
private int n1 = 100;
private void m2(){
System.out.println("m2");
}//私有方法
public void m1(){//方法
//1.局部内部类是定义在外部类的局部位置,通常在方法
//3.不能添加访问修饰符,但是可以使用final修饰
class Inner02{//局部内部类
private int n1 = 800;
public void f1(){
System.out.println("n1 =" + n1 + " 外部类的n1=" + Outer02.this.n1);
m2();
}
}
class Inner03 extends Inner02{
}
Inner02 inner02 = new Inner02();
inner02.f1();
}
//外部类在方法中,可以创建Inner02对象,然后调用方法即可
{//代码块
class Inner03{
}
}
}
匿名内部类(基于类,接口和抽象类)
优点:对于只使用一次,后面再不使用的类可以使用匿名内部类来简化开发
(1)可以直接访问外部类的所有成员,包含私有的
(2)不能添加访问修饰符,因为它的地位就是一个局部变量
(3)作用域:仅仅在定义它的方法或代码块中。
(4)匿名内部类访问外部类成员:直接访问
(5)外部其他类不能访问匿名内部类(因为 匿名内部类地位是一个局部变量)
(6)如果外部关和内部类的成员重名时。内部类访问的话,默认遵循就近原则,如果想
访问外部类的成员,则可以使用(外部类名.this.成员)去访问
匿名内部类的基本语法
new 类或接口(参数列表){
类体
};
内部类的使用:1.本质还是类。2.该类没有名字。3.同时还是一个对象
(1)基于接口的匿名内部类
A1 tiger = new A1(){
public void cry(){
System.out.println("老虎叫");
}
};
System.out.println("tiger的运行类型=" + tiger.getClass());
tiger.cry();
(2) 基于类的匿名内部类
Father father = new Father("jack"){
@Override
public void test() {
System.out.println("匿名内部类重写了test方法");
}
};
System.out.println("father的运行类型=" + father.getClass());//Outer04$2
father.test();
(3)基于抽象类的匿名内部类
Animal animal = new Animal() {
@Override
void eat() {
System.out.println("吃");
}
};
animal.eat();
System.out.println("animal的运行类型=" + animal.getClass());
成员内部类(定义在外部类的成员位置)
(1)可以直接访问外部类的所有成员,包含私有的
(2)成员内部类,是定义在外部类的成员位置上的可以添加任意访问修饰符,因为它的地位就是一个成员
(3)作用域 和外部类的其他成员一样,为整个类体,在外部类的成员方法中创
建成员内部类对象,再调用方法。
(4)成员内部类访问外部类(比如:属性):直接访问
(5) 外部类访问成员内部类:创建对象,再访问
(6)外部其他类访问成员内部类:
//第一种方式
Outer08.Inner08 inner08 = outer08.new Inner08();
//第二种方式 在外部类中,编写一个方法,可以返回 Inner08对象
Outer08.Inner08 inner08Instance = outer08.getInner08Instance();
//第三种方式
Outer08.Inner08 inner08_ = new Outer08().new Inner08();
(7)如果成员内部类的成员和外部类的成员重名,遵守就近原则可以通过外部类名.this.属性来访问外部类成员
package com.innerclass;
public class InnerClass01 { //外部其他类
public static void main(String[] args) {
Outer08 outer08 = new Outer08();
outer08.t1();
//外部其他类使用成员内部类的三种方式
Outer08.Inner08 inner08 = outer08.new Inner08();
Outer08.Inner08 inner08Instance = outer08.getInner08Instance();
Outer08.Inner08 inner08_ = new Outer08().new Inner08();
}
}
class Outer08{ //外部类
private int n1 = 10;
public String name = "张三";
public class Inner08{ //成员内部类
private int n1 = 66;
private double sal = 99.9;
public void say(){
System.out.println("n1 = " + n1 + " name = " + name + " 外部类n1=" + Outer08.this.n1);
}
}
public Inner08 getInner08Instance(){
return new Inner08();
}
public void t1(){
Inner08 inner08 = new Inner08();
inner08.say();
System.out.println(inner08.sal);
}
}
静态内部类(定义在成员位置 static)
(1)可以直接访问外部类的所有静态成员,包含私有的,但不能访问非静态的
(2)可以添加任意访问修饰符,因为它的地位就是一个成员
(3)作用域 和外部类的其他成员一样,为整个类体,在外部类的成员方法中创
建成员内部类对象,再调用方法。
(4)静态内部类访问外部类(比如:静态属性):直接访问所有静态成员
(5) 外部类访问静态内部类:创建对象,再访问
(6)外部其他类访问静态内部类:
//外部其他类 使用静态内部类
//方式1
//因为静态内部类是可以通过类名直接访问(前提是满足访问权限)
Outer10.Inner10 inner10 = new Outer10.Inner10();
inner10.say();
//方式2
//方法返回静态内部类实例
//非静态方法
Outer10.Inner10 inner101 = outer10.getInner10();
//静态方法
Outer10.Inner10 inner10_ = Outer10.getInner10_();
(7)如果静态内部类的成员和外部类的成员重名,遵守就近原则。可以通过(外部类名.成员)来访问 //不要加this