01内部类的定义
在java中内部类是将一个类定义在另一个类的方法或者类中,这样的类我们称它为内部类。
内部类可以分为四种:局部内部类、成员内部类、匿名内部类、静态内部类,下面我们逐一介绍这四种内部类。
02局部内部类
存在方法中的内部类叫局部内部类。
它与成员内部类的区别在于局部内部类的访问权限仅限于方法或作用域内。
class A{
public void sing(){
class B{
}
}
}
我们类比局部变量可以知道,它也不能访问修饰符以及static修饰符。
03成员内部类
他定义在另一个类中。一般定义格式如下
class C{
class D{
}
}
谁在里面谁是内部类,谁在外面谁是外部类。显然C是外部类,D是内部类。
对于内部类而言可以访问外部类的成员和方法,外部类不能直接访问内部类的属性和方法,要想访问必须要创建一个内部类对象,然后通过该对象来访问。
成员内部类访问外部类的属性和方法
class C{
private String name = "外部类";
public void walk(){
System.out.println("外部类散步");
}
class D{
public void say(){
System.out.println(name);
run();
}
}
外部类去访问内部类方法和属性
Class C{
private String name = "外部类";
public void walk(){
System.out.println("外部类散步");
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
public void say(){
System.out.println(name);
run();
}
}
}
外部类方法和属性隐藏
如果成员内部类的属性或者方法与外部类的同名,将导致外部类的这些属性与方法在内部类被隐藏,也可按照该格式调用,外部类.this.属性/方法。
class C{
private String name = "外部类";
public void walk(){
System.out.println("外部类散步");
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "内部类";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
创建内部类对象
显然成员内部类是寄生于外部类,创建内部类对象就必须先创造外部类对象。之后创建内部类有两种方式。
public class Test10 {
public static void main(String[] args) {
/*方式1创建成员内部类对象*/
C c = new C();
C.D d = c.new D();
/*方式2创建成员内部类对象*/
C.D d1 = c.getClassD();
}
}class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
/*创建一个返回D对象的方法*/
public D getClassD(){
return new D();
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "内部类";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
成员内部类的访问权限
成员内部类前可加上四种访问修饰符。
private:仅外部类可访问。
protected:同包下或继承类可访问。
default:同包下可访问。
public:所有类可访问。
04静态内部类
成员内部类多了一个static修饰符就变成静态内部类了。它一般不依赖于外部类。它的特点,静态内部类不能使用外部类的非静态变量与方法。
同时可以知道成员内部类里面是不能含静态属性或方法的.
class E {
static class I {
}
}
05匿名内部类
public class TestF {
public static void main(String[] args) {
driveCar(new Car(){
@Override
public void drive() {
System.out.println("驾驶着BMW汽车");
}
});
}
public static void driveCar(Car car){
car.drive();
}
}
interface Car {
void drive();
}
分析以上代码知道静态方法driveCar需要一个Car对象,我们通过实现接口创建一个匿名类对象传递过去。事实上还可以通过继承类来创建一个匿名内部类对象。
注意事项:匿名内部类没有构造方法。也是唯一没有构造方法的内部类。匿名内部类和局部内部类只能访问外部类的final变量。
内部类的好处
方便写事件驱动程序
完善了Java多继承机制,由于每一个内部类都可以独立的继承接口或类,所以无论外部类是否继承或实现了某个类或接口,对于内部类没有影响。