内部类的定义
在java中,可以把一个类定义在另一个类里或者方法里,这样的类称为内部类
内部类的特点
- 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围对象信息相互独立
- 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类
- 每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
- 内部类最大的优点就在于它能够非常好的解决多重继承的问题
- 内部类提供了更好的封装,除了该外围类,其他类都不能访问。私有内部类;
内部类的分类
在java中一共有四种内部类,它们分别是:成员内部类、静态内部类、局部内部类、匿名内部类
成员内部类
- 成员内部类定义在一个类里
// 外部类
public class Outside {
// 成员内部类的定义
public class Inside {
public void test() {
System.out.println("我是成员内部类中的方法");
}
}
}
-
成员内部类不能存在任何static的变量和方法
-
成员内部类是依附于外部类的,如何要创建内部类对象,就必须先创建外部类对象。
// 外部类
public class Outside {
private Inside inside = null;
// 成员内部类的定义
public class Inside {
public void test() {
System.out.println("我是成员内部类中的方法");
}
}
public Inside getInside() {
if (inside == null) {
inside = new Inside();
}
return inside;
}
public static void main(String[] args) {
// 外部类对象
Outside ot = new Outside();
// 成员内部类依附于外部类
Inside ins = ot.new Inside();
// 第二种创建对象的方式
Inside ins2 = ot.getInside();
ins.test();
ins2.test();
}
}
-
当成员内部类中拥有和外部类同名的变量和方法时,会发生隐藏。内部类调用成员时默认情况下是访问成员内部类的成员。
-
成员内部类可以无条件的访问外部类的属性和方法,包括私有和静态成员。
// 外部类
public class AOut {
// 私有属性
private int a = 20;
// 静态属性
public static int b = 10;
public int getB() {
return a;
}
public void setB(int b) {
this.a = b;
}
// 外部类同名方法
public void test() {
System.out.println("外部类方法");
}
// 外部类静态方法
public static void test2() {
System.out.println("外部类静态方法");
}
// 成员内部类
public class Ain {
// 成员内部类的属性
public int a = 30;
// 成员内部类的方法
public void test() {
// 成员内部类局部变量
int a = 40;
System.out.println("成员内部类的方法");
// 调用的是成员内部类方法中的局部变量
System.out.println(a);
// 调用当前成员内部类对象的成员属性
System.out.println(this.a);
// 调用外部类对象的私有同名属性
System.out.println(AOut.this.a);
// 调用外部类的静态属性
System.out.println(AOut.b);
// 调用外部类同名方法
AOut.this.test();
// 调用外部类静态方法
AOut.test2();
}
}
public static void main(String[] args) {
AOut ao = new AOut();
// 实例化成员内部类对象
Ain bi = ao.new Ain();
bi.test();
}
}
静态内部类
- 静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static
- 静态内部类是不需要依赖于外部类的
- 静态内部类不能使用外部类的非static成员变量或者方法
// 外部类
public class BOut {
// 非静太属性
public int a = 10;
// 静态内部类
static class Bin {
public void test() {
System.out.println("静态内部类的方法");
// 不能调用外部类非静态的属性和方法
// System.out.println(Bout.this.a);
}
}
public static void main(String[] args) {
// 不需要依靠外部类来创建对象
Bin ci = new Bin();
ci.test();
}
}
局部内部类
- 局部内部类是定义于方法之中的
- 局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。
// 外部类
public class COut {
// 外部类方法
public COut test() {
// 在方法中定义的类是局部内部类
class Cin extends COut {
}
return new Cin();
}
}
匿名内部类
-
使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
-
匿名内部类中是不能定义构造函数的。
-
匿名内部类中不能存在任何的静态成员变量和静态方法。
-
匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
-
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
-
匿名内部类是唯一一种没有构造器的类,并且只能创建一个该类的对象。
// 定义一个接口
public interface PrintAble {
void print();
}
public class DemoAnonymous {
public static void main(String[] args) {
// 创建匿名内部类对象
PrintAble pa = new PrintAble() {
@Override
public void print() {
System.out.println("我是匿名内部类重写接口中的方法");
}
};
// 调用匿名内部类方法
pa.print();
}
}
关于四种内部类的初步学习和总结。