内部类分为四种
- 成员内部类(位于外部类成员位置)
- 局部内部类(位于外部类的成员方法内)
- 静态内部类(static 修饰的成员内部类)
- 匿名内部类(就是一个对象)
- 内部类应用:迭代器、创建接口/抽象类的对象
成员内部类:
成员内部类:可以访问外部类的任意成员变量和方法;外部类访问内部类的成员变量和方法需要使用内部类对象
public class Outer {
private static String name;
public void setName(String s){
this.name = s;
}
//成员内部类
//可以访问外部类任意方法和成员变量
class Inner{
private String describe = "woditiana";
private void show(){
System.out.println(describe+"==="+name);
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
}
//外部类要想访问内部类的成员变量(包括私有变量)或方法(私有方法)
public void outerShow(){
System.out.println(new Inner().describe);
new Inner().show();
}
}
Question1?
私有变量只能本类内访问,为什么外部类也能访问成员内部类的私有变量?
答:成员内部类和成员变量和成员方法位置一样,相当于外部类的成员变量/成员方法。因此,外部类可以访问内部类的全部变量和方法.
Question2?
成员内部类前修饰符:private, protected, public, default, static作用是什么?
答:private声明内部类是外部类私有的,在其他类中不能创建该内部类。
protected声明内部类只能本包或其子类访问。
public 任何类都能访问此内部类(即创建该内部类的对象
default声明该内部类只能由同一包下类访问。
static声明该内部类是静态内部类。
局部内部类:
局部内部类:在类的方法中定义的类,能够访问外部类的任何成员变量和成员方法,外部类访问内部类需要创建内部类的对象
public class Outer {
private static String name;
public void setName(String s){
this.name = s;
}~
public void get(){
class MInner{
private int age;
private void showAge(){
System.out.println("==="+age+"===");
System.out.println(name);
outerShow();
}
}
MInner mInner = new MInner();
mInner.showAge();
}~
}
Question1?
局部内部类为什么不能用private、protected、default、public、stati修饰?
答:这和成员方法中的变量也不能由这些修饰符修饰是一样的,因为成员方法已经由这些访问限定词限定了,如果成员方法中的局部变量和局部类也有访问限定词限定,会和成员方法的限定冲突,因此java规定成员方法中的局部变量和局部类不能有限定词修饰。
Question2?
外部类的其他成员方法能否访问到该局部类?
答:既然内部类被定义到成员方法内,那么它的作用范围就是该成员方法内。其他成员方法不能访问该局部内部类。当然有种情况是:成员方法内的局部类实现了一个外部类可见接口,那么该成员方法将局部内部类向上转型后返回,那么其他成员方法可以调用该成员方法,然后接收就行了。记住无论什么情况下,其他成员方法都不能直接new 出这个局部内部类。
接口:
public interface MInnerIterface {
public void showAge();
}
~
局部内部类:
public class Outer {
private static String name;
public void setName(String s){
this.name = s;
}~
public void outerShow(){
System.out.println(new Inner().describe);
//调用get(),用接口接收局部内部类
MInnerIterface mInnerIterface = get();
mInnerIterface.showAge();
}~
public MInnerIterface get(){//必须向上转型返回,因为局部内部类对于其他成员方法不可见
class MInner implements MInnerIterface{
private int age;
public void showAge(){
System.out.println("++++"+age+"++++");
System.out.println(name);
}
}
MInner mInner = new MInner();
mInner.showAge();
return mInner;
}~
}
静态内部类
静态内部类:成员内部类由static修饰,只能访问外部类的静态变量和静态方法,创建内部类对象无需使用外部类对象。
public class Outer {
private static String name;
public void setName(String s){
this.name = s;
}~
static class StaticInner{
private String nickname = "doggy";
public void show(){
System.out.println(name+":"+nickname);
}
}~
}
创建静态内部类对象
public class Test {
public static void main(String[] args) {
Outer.StaticInner staticInner = new Outer.StaticInner();
}
}~
匿名内部类:
匿名内部类就是一个对象:
接口
public interface MInnerIterface {
public void showAge();
}
~
匿名类
public class Test {
public static void main(String[] args) {
MInnerIterface iterface = new MInnerIterface() {
public void showAge() {
System.out.println("show age");
}
};
}~
由此可以看出匿名类就是一个对象,创建方法:new 接口/抽象类。作用是不用编写一个实现类就可以使用接口/抽象类的对象
创建成员内部类对象
public class Test {
public static void main(String[] args) {
// 外部类
Outer outer = new Outer();
// 成员内部类:需要外部对象
Outer.Inner inner = outer.new Inner();
// 一般外部类会提供获得成员内部类对象的方法如:迭代器
Outer.Inner inner1 = outer.getInner();
// 静态类(static 修饰的成员内部类)无需外部类对象
Outer.StaticInner staticInner = new Outer.StaticInner();
}
}
~