1 内部类的概念
1.1 内部类的分类
定义在外部类的局部位置
- 局部内部类
- 匿名内部类
定义在外部类的成员位置
- 成员内部类
- 静态内部类
1.2 类的五大成员
属性、方法、构造器、代码块和内部类
2 局部内部类
2.1 局部内部类的特征
- 可以直接访问外部类的所有成员,包括私有的
- 不能添加访问修饰符,因为它的地位是局部变量。局部变量是不可以使用修饰符的,但可以使用final修饰
- 作用域:仅仅在定义它的方法或代码块中
- 如果外部类和局部内部类的成员重名,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
2.2 局部内部类的测试
public class LocalClass {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outer_m();
}
}
class Outer { //外部类
private int n = 10;
public void outer_m() {
final class LocalInner { //局部内部类
private int n = 100;
public void inner_m() {
System.out.println("inner method...");
System.out.println("n=" + n + " outer n=" + Outer.this.n);
}
}
LocalInner localInner = new LocalInner();
localInner.inner_m();
}
}
3 匿名内部类
3.1 匿名内部类的特征
- 想要使用某接口,传统的方式需要写一个类实现该接口,并创建对象。然而该对象实际上只是使用一次,后面不再使用,可以使用匿名内部类的方式来简化开发
- 编译类型为接口类型,允许类型为匿名内部类
- 不能提那就访问修饰符,因为它的地位是一个局部变量
- 作用域:仅仅在定义它的方法或代码块中
- 如果外部类和匿名内部类的成员重名,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
3.2 匿名内部类的测试
public class AnnoClass {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outer_m();
}
}
class Outer {
private int n = 10;
public void outer_m() {
//类似 public class Outer$1 implements IFly
IFly bird = new IFly() {
private int n = 100;
@Override
public void fly() {
System.out.println("bird fly...");
System.out.println("n=" + n + " outer_n=" + Outer.this.n);
}
};
bird.fly();
//类似 public class Outer$2 extends Animal
Animal dog = new Animal(){
@Override
public void eat() {
System.out.println("dog eat...");
}
};
dog.eat();
}
}
interface IFly {
public void fly();
}
class Animal {
public void eat() {
System.out.println("animal eat...");
}
}
- result
bird fly...
n=100 outer_n=10
class com.yqj.innerclass.Outer$1
dog eat...
class com.yqj.innerclass.Outer$2
4 成员内部类
4.1 成员内部类的特征
- 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位是一个成员
- 作用域:和外部类的其他成员一样,为整个类体
- 如果外部类和成员内部类的成员重名,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
4.2 成员内部类的使用
public class MemberClass {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner1 = outer.new Inner();
inner1.inner_m();
System.out.println(inner1);
Outer.Inner inner2 = outer.getInner();
inner2.inner_m();
System.out.println(inner2);
Outer.Inner inner3 = new Outer().getInner();
inner3.inner_m();
System.out.println(inner3);
}
}
class Outer{
private int n = 10;
private void outer_m(){
System.out.println("outer method...");
}
public class Inner{
private int n = 100;
public void inner_m(){
outer_m();
System.out.println("n="+100 + " outer_n="+Outer.this.n);
}
}
public Inner getInner(){
return new Inner();
}
}
- result
outer method...
n=100 outer_n=10
com.yqj.innerclass.Outer$Inner@677327b6
outer method...
n=100 outer_n=10
com.yqj.innerclass.Outer$Inner@14ae5a5
outer method...
n=100 outer_n=10
com.yqj.innerclass.Outer$Inner@7f31245a
5 静态内部类
5.1 静态内部类特征
- 可以访问外部类的静态成员,包含私有的,但是不能直接访问非静态成员
- 可以添加任意访问修饰符,因为它相当于成员
- 作用域:整个类体
- 如果外部类和静态内部类的成员重名,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问
5.2 静态内部类的使用
public class StaticClass {
public static void main(String[] args) {
Outer.Inner inner1 = new Outer.Inner();
inner1.inner_m();
Outer.Inner inner2 = new Outer().getInner1();
inner2.inner_m();
Outer.Inner inner3 = Outer.getInner2();
inner3.inner_m();
}
}
class Outer {
private static int n = 10;
public static class Inner {
private int n = 100;
public void inner_m() {
System.out.println("n=" + n + " outer_n=" + Outer.n);
}
}
public Inner getInner1(){
return new Inner();
}
public static Inner getInner2(){
return new Inner();
}
}
- result
n=100 outer_n=10
n=100 outer_n=10
n=100 outer_n=10
网友评论