1.定义
内部类是指在一个外部类的内部再定义一个类。
2.性质
①内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
②内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
③内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量。(这与类中的静态成员方法只能访问静态成员是类似的)
3.作用
①内部类可以很好的实现隐藏,一般的非内部类,是不允许有private和protected访问权限,但内部类可以。
②内部类拥有外围类的所有元素的访问权限。
③可是实现多重继承。
④可以避免修改接口而实现同一个类中两种同名方法的调用。
4.分类
java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。
4.1成员内部类
成员内部类,直接定义在类中。就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
成员内部类可用访问权限修饰符public,protected,friendly(默认),private。
public static void main(String[] args) {
Joo joo = new Joo();
//获取内部类实例
Noo noo = joo.new Noo();
System.out.println(noo.b);
noo.show();
}
}
//外部类
class Joo{
private int a = 10;
class Noo{
public int b = 20;
public void show() {
System.out.println(a+b);
}
}
public void show() {
Noo noo = new Noo();
System.out.println(noo.b);
}
}
4.2局部内部类
局部内部类,是指内部类定义在方法和作用域内。
局部内部类只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的。
局部内部类可用访问权限修饰符只有friendly(默认)。
定义在方法内:
public class LocalInnerClass {
public static void main(String[] args) {
int a = 20;
class Hoo{
int b = 20;
public void show(){
System.out.println(b+a);
//System.out.println(a++); 内部类允许访问外部的局部变量,但不能改变其值
}
}
Hoo hoo = new Hoo();
hoo.show();
}
4.3静态内部类
与成员内部类定义的唯一区别是前面加了一个static的修饰符。
静态内部类,不需要内部类对象和外部类对象之间的联系。
静态内部类和成员的内部类还有两个个区别:
①成员内部类不能有static数据和static属性,也不能包含静态内部类,但静态内部类可以。
②创建内部类对象时静态内部类必须用Outer.Inner,成员内部类可以用Outer.Inner,也可以用Inner。
public class StaticInnerClassDemo {
public static void main(String[] args) {
//实例化外部类
Foo foo = new Foo();
// 如何实例化内部类。
Koo koo = new Foo.Koo();
System.out.println(koo.b);
koo.show();
}
}
class Foo{
private static int a =10;
static class Koo{
public int b = 20;
public void show(){
System.out.println("hello innerclass"+a);// 能够访问外部静态变量。
}
}
4.4匿名内部类
匿名内部类是不能加访问修饰符的。即它的访问权限修饰符只能是friendly(默认的)。
要注意的是,new 匿名内部类,这个类是要先定义的。
匿名内部类实际上就是继承一个已经存在的类,但是省略自身类的名字。
当所在的方法的形参需要被内部类里面使用时,该形参必须为final。
public static void main(String[] args) {
// 实例化匿名内部类。
Aoo aoo = new Aoo(){
public void show(){
System.out.println("hello zhangsan");
}
};
aoo.show();
System.out.println("************");
new Aoo(){
public void show() {
System.out.println("匿名内部类");
}
}.show();
// 匿名内部类,重写抽象类方法。
new Coo() {
@Override
public void getCoo() {
System.out.println(" 匿名内部类,重写抽象类方法。");
}
}.getCoo();
//匿名内部类获取实例
Doo doo = new Doo(){
public void getDoo() {
}
};
doo.getDoo();
}
}
//普通类
class Aoo{
public int a = 10;
public void show(){
System.out.println(a);
}
}
//子类继承父类
class Boo extends Aoo{
public void show() {
System.out.println("hello word");
}
}
//抽象类
abstract class Coo{
public abstract void getCoo();
}
//接口
interface Doo{
public abstract void getDoo();
}