java内部类学习

java内部类学习:

  • 内部类的作用:
    • 1.内部类可以很好的实现隐藏
    • 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
    • 2.内部类拥有外围类的所有元素的访问权限
    • 3.可是实现多重继承(使用内部类去继承其他类实现 外部类的间接多继承)
    • 4.可以避免修改接口而实现同一个类中两种同名方法的调用。
    • (继承的父类和实现的接口类中的方法名相同时,可以用内部类来实现接口,外部类继承其他类,这样就不会与外围类的方法冲突了)

注意:
1.内部类可以随意的访问外部类的成员。包括private等修饰符修饰的变量和方法。但是外部类不能轻松的访问内部类的成员,必须常见一个内部类的实例再去访问。
2.内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。

  • 内部类的类型:
    成员内部类:成员内部类是最普通的内部类,定义在主类体内部的类,类似该类的成员。成员内部类是依附外部类而存在的.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public class Test {
    public static void main(String[] args) {
    //第一种方式:
    Outter outter = new Outter();
    Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
    //第二种方式:
    Outter.Inner inner1 = outter.getInnerInstance();
    }
    }
    class Outter {
    private Inner inner = null;
    public Outter() {}
    //获取内部类实例对象的方法(单例模式)
    public Inner getInnerInstance() {
    if(inner == null)
    inner = new Inner();
    return inner;
    }
    class Inner {
    public Inner() { }
    }
    }

局部内部类:局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

1
2
3
4
5
6
7
8
9
10
11
12
13
class People {
}
class Man {
//局部内部类
public People getWoman() {
class Woman extends People { //局部内部类
int age = 23;
}
return new Woman();
}
}

匿名内部类:
1、 匿名内部类是没有访问修饰符的。
2、 new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错。
3、 注意getInnerClass()方法的形参,第一个形参是用final修饰的,而第二个却没有。同时我们也发现第二个形参在匿名内部类中没有使用过,所以当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
4、 匿名内部类是没有构造方法的。因为它连名字都没有何来构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class OuterClass {
public InnerClass getInnerClass(final int num,String str2){
return new InnerClass(){
int number = num + 3;
public int getNumber(){
return number;
}
}; /* 注意:分号不能省 */
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
//inner.method4();
}
}
interface InnerClass {
int getNumber();
}
//class InnerClass{
// int getNumber(){};
//
// public void method4() {
// System.out.println("匿名内部类 method4");
// }
//}

静态内部类:static声明的内部类。静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test {
public static void main(String[] args) {
//不依赖外部类的实例去创建静态内部类的实例对象
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}