内部类的定义:
内部类就是定义在另一个类里面的类。反之,包含内部类的类称为外部类。
我们为什么要使用内部类呢?
1.外部类能给内部类提供更好的封装,把内部类隐藏在外部类之内,不允许同一个包中的其他类去访问。
2.内部类能直接访问外部类的所有数据,包括私有数据。
3.内部类实现的功能,外部类也能使用。
内部类分为:
1.成员内部类
2.静态内部类
3.方法内部类
4.匿名内部类
下面在下就详细说说这个4中内部类:
1.成员内部类:
在其外部类中被定义,与成员变量,方法并列。
package org.member.innerclass; public class Big { //定义一个整形变量 private int i = 10; //定义一个整形变量 private int k = 20; //定义一个静态整形变量 private static int j = 30; //定义一个方法 public void method1() { System.out.println( "method1..." ); } //定义一个静态方法 public static void method2() { System.out.println( "method2..." ); } //定义成员内部类 class Small { //内部类和外部类的成员变量能够共存的 //定义一个整形变量 private int i = 11; //定义内部的方法 public void innerMethod() { //输出内部整形变量i的值 System.out.println( "内部类i的值 = " + i ); //这里指定的是内部类的整形变量i System.out.println( "内部类i的值 = " + this.i ); //输出外部类整形变量i System.out.println( "外部类i的值 = " + Big.this.i ); //直接输出外部类的静态整形变量 System.out.println( "静态变量j = " + j ); //内部类和外部类没有同名的变量,则直接用变量名访问外部类变量 System.out.println("外部类k的值 = " + k ); //内部类访问外部类的方法 method1(); //内部类访问外部类的静态方法 method2(); } }//在方法内访问内部类 public void method3() { //实例化一个内部类 Small small = new Small(); //调用其方法 small.innerMethod(); } //外部类的静态方法访问内部类 //与外部类访问内部类一样 public static void method4() { //首先得实例化一个外部类 Big big = new Big(); //然后实例化内部类 Small small = big.new Small(); //调用内部类的方法 small.innerMethod(); } public static void main(String[] args) { //想要创建内部类,就必须使用一个外部类来引用创建 Big big = new Big(); Big.Small small = big.new Small(); small.innerMethod(); //通过外部类的方法来创建内部类 big.method3(); } }
2.静态内部类
静态内部类跟成员内部类不同,它没有隐含的保存一个引用,指向创建它的外部类,它不需要与外部类有联系,它只是嵌套在外部类中,所以我们也称它为”嵌套类“。
”嵌套类“意味着:
1.并不需要外部类来创建嵌套类对象。
2.不能从嵌套类对象中访问非静态的外部类。
package org.static1.innerclass; public class Big { //定义一个静态整形变量 private static int i = 10; //定义一个整形变量 private int j = 20; //外部类的静态方法 public static void method1() { System.out.println( "静态method1方法" ); } //外部类的方法 public void method2() { System.out.println( "method2方法" ); } //静态内部类 static class Small2 { //定义一个静态整形变量 private static int inner_i = 30; //定义一个整形变量 private int inner_j = 40; //静态内部类的静态方法只能调用静态变量和静态方法 //静态内部类的静态方法 public static void innerMethod() { //静态内部类的静态方法只能输出静态变量 System.out.println( "静态整形变量inner_i = " + inner_i ); //输出外部类的静态变量 System.out.println( "外部类的静态变量i = " + i ); //调用外部类的静态方法 method1(); } //静态内部类的方法 public void innerMethod2() { //内部类的非静态方法输出非静态变量 System.out.println( inner_j ); //静态内部类不能调用外部类的非静态方法和非静态变量 // method2(); // System.out.println( j ); } } //外部类的方法 public static void method3() { //外部类访问静态内部类的的静态变量 System.out.println( "inner_i = " + Small2.inner_i ); //外部类访问静态内部类的的静态方法 Small2.innerMethod(); //外部类访问内部类的非静态变量 //先得实例化一个内部类对象 Small2 small2 = new Small2(); System.out.println( "inner_j = " + small2.inner_j ); //外部类访问内部类的非静态方法 small2.innerMethod2(); } //main方法 public static void main(String[] args) { Small2.innerMethod(); //静态内部类是不需要外部类的引用来创建对象的 Small2 small2 = new Small2(); small2.innerMethod2(); } }
3.局部内部类
在方法中定义的类,我们称为局部内部类。与局部变量类似,局部内部类不能有访问修饰符,但是它可以访问当前代码块内的常量,和此外部类所有的成员。
package org.local.innerclass; public class Big { //定义整形变量 private int i = 10; //整形变量 private int out_j = 20; //定义一个方法 public void method() { //定义局部整形常量 final int i = 15; //定义局部整形变量 int j = 25; //局部内部类 class Small { //可以定义与外部类一样的变量名 int i = 100; //不能定义静态变量 // static int m = 10; private void method() { //如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量 System.out.println( "out_j = " + out_j ); //输出局部内部类的成员变量 System.out.println( "i = " + i ); //输出外部类的成员变量 System.out.println( "Big.this.i = " + Big.this.i ); //该内部类可以访问局部变量 System.out.println( "j = " + j ); } } new Small().method(); } public static void main(String[] args) { Big big = new Big(); big.method(); } }
4.匿名内部类
顾名思义,匿名内部类就是没有名字的内部类。
在一下情况使用匿名内部类比较合适:
.只用到类的一个实例。
.类在定义后马上能用到。
.类非常小。
.给类命名不会导致你的代码更容易被理解。
在使用匿名内部类,要记住一下几个原则:
.匿名内部类不能有构造方法。
.匿名内部类不能定义任何静态成员、方法、类。
.匿名内部类不能是public,protected,private,static。
.只能创建匿名内部类的一个实例.
.一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
.因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
package org.anonymous.innerclass; public abstract class Doctor { //定义方法 public void workInDay() { System.out.println( "在医院上班" ); } //定义抽象方法 public abstract void workInNight(); //main方法 public static void main(String[] args) { //实例化Doctor类,而且必须重写workInNight抽象方法 Doctor doctor = new Doctor() { //重写该方法 @Override public void workInNight() { System.out.println( "睡觉" ); } }; //调用其方法 doctor.workInDay(); doctor.workInNight(); } }
-----------------------