博客源为书写的载体,书写以对思维的缓存 正文

Java 内部类


Java内部类(Inner Class )就是定义在另外一个类里面的类,而包含内部类的类被称为外部类。内部类可分为以下几种:成员内部类、静态内部类、方法内部类、匿名内部类,今日逐一总结,他日加以复用。

一:成员内部类

成员内部类:内部类中最常见的就是成员内部类,也称为普通内部类。

public class Outer{
   private String name = "叶文洁";
   // 成员内部类Inner
   public class Inner{
       int age = 20;
       public void showMessage(){
           System.out.println(name + age);
       }
   }
}
   
public class Test{
   public static void main(String[] args){
       // 先创建外部类对象
       Outer o = new Outer();
       // 再通过外部类对象来创建内部类对象
       Outer.Inner i = o.new Inner();
       // 最后调用内部类方法
       i.showMessage();
   }
}
注意点:
1.内部类可以使用任意访问修饰符如:public、protected、private等。
2.内部类中的方法可以直接访问外部类的所有数据,但外部类不能直接访问内部类的成员或方法。
3.成员内部类必须使用外部类对象来创建内部类对象,而不能直接去new一个内部类对象。
4.编译上面的程序后会产生了两个.class文件:Outer.class(外部类)和Outer$Inner.class(内部类)。
5.成员内部类的.class文件格式为:外部类名$内部类名.class。
6.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问的是自己的成员变量或方法。

(1)针对于上面第1点,如果成员内部类Inner用<private>修饰,则只能在外部类的内部访问;如果用<public>修饰,则任何地方都能访问;如果用<protected>修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是<默认>访问权限则和外部类时的访问权限不同--只能在同一个包下访问。

(2)针对于上面第2点,如果外部类要访问内部类的成员变量或方法,必须创建一个内部类对象来进行访问:

public class Outer{
   private String name = "叶文洁";
   
   public void show(){
       System.out.println("访问内部类的age变量:" + new Inner().name);
   }
   // 内部类
   public class Inner{
       private int age = 21;
   }
}

(3)针对于上面第6点,在重名的情况下如果要访问外部类的成员变量或方法需要这样:外部类.this.成员变量/方法():

public class Outer{
   private String name = "叶文洁";
   
   public String show(){
       return name;
   }
   // 内部类
   public class Inner{
       private String name = "杨冬";
       
       public void showMessage(){
           System.out.println("访问外部类的name变量:" + Outer.this.name);
           System.out.println("访问外部类的show方法:" + Outer.this.show());
       }
   }
}

二:静态内部类

静态内部类:定义在另一个类里面的类,只不过在类的前面多了一个关键字"static"。

public class Outer{
   private String name = "叶文洁";
   private static int age = 21;
   private static char sex = '女';
   
   // 静态内部类Inner
   public static class Inner{
       private int age = 20;
       public void showMessage(){
           // 访问外部类"非静态成员"
           System.out.println("外部类非静态变量name:" + new Outer().name);
           // 访问外部类"同名静态变量"age
           System.out.println("外部类同名静态变量age:" + Outer.age);
           // 访问外部类"未重名静态变量"sex
           System.out.println("外部类静态变量sex:" + sex);
       }
   }
}

public class Test{    
   public static void main(String[] args){
       // 直接创建静态内部类对象
       Outer.Inner i = new Outer.Inner();
       // 调用静态内部类方法
       i.showMessage();
   }
}
注意点:
1.静态内部类不能直接访问外部类的非静态成员,需要通过"new 外部类().成员"的方式访问。
2.如果外部类的静态成员与内部类的成员名称相同,可通过"类名.静态成员"访问外部类的静态成员。
3.如果外部类的静态成员与内部类的成员名称不相同,则通过"成员名"直接调用外部类的静态成员。
4.创建静态内部类的对象时,不需要外部类的对象。

三:方法内部类

方法内部类:内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。

public class Outer{
   // 外部类方法
   public void show(){
       // 方法内部类Inner
class Inner {
   int score = 83;
   public void getScore(){
System.out.println(score);
           }
}
// 创建方法内部类对象
Inner i = new Inner();
// 调用方法内部类方法
i.getScore();
   }
}

public class Test{
   public static void main(String[] args){
       Outer o = new Outer();
       o.show();
   }
}
注意点:
1.方法内部类只能在外部类的方法中使用。
2.方法内部类不能使用public、protected、private等访问控制符和static修饰符。

四:匿名内部类

匿名内部类:没有名字的内部类。

abstract class Person{
   public abstract void show();
}

public class Test{
   public static void main(String[] args){
       // 匿名内部类
       Person p = new Person(){
           public void show(){
               System.out.println("匿名内部类");
           }
       };
       p.show();
   }
}
注意点:
1.匿名内部类也是不能有访问修饰符和static修饰符的。
2.匿名内部类不可以定义任何静态成员和方法。
3.要使用匿名内部类则必须继承一个父类或实现一个接口。
4.匿名内部类没有构造方法,如果匿名内部类继承了一个只含有带参构造方法的父类,在创建它的对象的时   候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容。

五:总结--内部类的作用

1.内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。

2.内部类的方法可以直接访问外部类的所有数据,包括私有的数据。

3.内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。

4.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。因此     内部类使得Java的多继承机制变得更加完善。

六:最后

images (6).jpg