JAVA:内部类和匿名内部类

接口中的内部类

  在我们实际开发过程中,如果想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用,那么接口内部的嵌套类会显得很方便.也就是说在接口中可以含有内部类.在这里,向大家展示接口中放置普通成员内部类和抽象成员内部类的情况.
 
1.首先创建接口,接口中定义了普通内部类InnerClass和抽象内部类AbInnerClass

package com.diandian.inter;
// 接口IOuterInterface
public interface IOuterInterface{
      int TEMP = 100; // 常量
      void abMethod();// 抽象方法
      public default void deMethod(){ // jdk1.8后可添加
            System.out.println("接口中默认方法");
      }
      public static void stMethod() {
            System.out.println("接口中静态方法");
      }
// 普通内部类
public class InnerClass{
        public void show(){
              System.out.println("接口中可定义普通成员内部类");
        }
}
// 抽象内部类
public abstract class AbInnerClass{
        public abstract void abInfo();
        public void info(){
            System.out.println("接口中可定义抽象成员内部类");
        }
}
}

2.普通成员内部类的实例化

// 创建接口的实现类ClassDemo
package com.diandian.inter;
// 实现类ClassDemo
public class ClassDemo implements IOuterInterface{
    @Override
    public void abMethod(){
        System.out.println("实现类");
    }
    // 获取接口中内部类方法
    public InnerClass getInner(){
        return new InnerClass();
    }
}

      // 获取普通内部类对象,调用方法
  package com.diandian.test;
  import com.diandian.inter.ClassDemo;
  import com.diandian.inter.IOuterInterface;
  import.com.diandian.inter.IOuterInterface.InnerClass;
    // 测试类:普通成员内部类
public class Test{
    public static void main(String[] args){
          /**第一种实例化对象方式:
              通过接口名.类名 进行实例化
            */
          IOuterInterface.InnerClass inner = new IOuterInterface.InnerClass();
          inner.show();
          /**第二种实例化对象方式:
              通过在实现类中创建接口中内部类获取方法
              用实现对象调用获取方法
          */
          ClassDemo demo = new ClassDemo();
          demo.getInner().show();
        /**第三种实例化对象方式:
            将内部类导入后,直接实例化
        */
          InnerClass innerTwo = new InnerClass();
          innerTwo.show();
    }
}

运行结果:

接口中可定义普通成员内部类
接口中可定义普通成员内部类
接口中可定义普通成员内部类

3.抽象成员内部类的实例化

    // 创建接口的实现类AbClassDemo
    package com.diandian.inter;
    // 实现类AbClassDemo
    public class AbClassDemo implements IOuterInterface{
        @Override
          public void abMethod(){
                
          }
          // 继承抽象类AbInnerClass
        public class AbDemo extends AbInnerClass{
            @Override
              public void abInfo(){
                  System.out.println("重写接口中抽象内部类中的抽象方法");
              }
         }
    }

获取抽象内部类对象,调用方法

package com.diandian.test;
import com.diandian.inter.AbClassDemo;
import com.diandian.inter.IOuterInterface;
// 测试类:抽象成员内部类
public class TestOne{
    public static void main(String[] args){
    /*第一种实例化对象方式:
      通过接口名.类名 进行实例化
      但是对于抽象类而言,不能直接实例化,所以这里可使用匿名内部类的方式
    */
     IOuterInterface.AbInnerClass abInner = new IOuterInterface.AbInnerClass(){
        public void abInfo(){
              System.out.println("重写抽象类中的抽象方法");
        }
    };
    abInner.abInfo();
    abInner.info();
    System.out.println("=====================");
    /*第二种实例化方法:
        在实现类中定义内部类继承接口中的抽象内部类
    */
    IOuterInterface.AbInnerClass abInnerOne = new AbClassDemo().new AbDemo();
    abInnerOne.abInfo();
    abInnerOne.info();
}
}

运行结果:
重写抽象类中的抽象方法
接口中可定义抽象成员内部类
========================
重写接口中抽象类中的抽象方法
接口中可以定义抽象成员内部类

匿名内部类

概念

匿名内部类也及时没有名字的内部类
正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写但使用匿名内部类还有个前提条件:必须继承一个父类或者一个接口
注意事项:

  • 编译后的文件名:外部类$数字.class
  • 无法使用publick,private,abstract,static修饰,匿名内部类不能出现抽象方法
  • 无法编写构造方法,但可以添加构造代码块
  • 不能出现静态成员
  • 匿名内部类可实现接口也可以继承类,但是不可兼得
  • 匿名内部类不能是抽象类的,它必须要实现继承的类或者实现接口的所有抽象方法
     

匿名内部类初始化

  我们一般都是利用构造器来完成某个实例的初始化工作,但是匿名内部类是没有构造器的,那怎么来初始化匿名内部类呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果.
实例:
先定义一个接口,然后定义该接口的匿名内部类.

    public interface InnerClass{
        public String getName();
        public int getAge();
    }
    public class OutClass{
      public InnerClass getInnerClass(final int age,final String name){
          return new InnerClass(){
              int age_;
              String name_;
              // 构造代码块完成初始化工作
              {
                    if(0 < age && age < 200){
                          age_ = age;
                          name_ = name;
                    }
              }
              public String getName(){
                    return age_;
              }
          };
      }
      public static void main(String[] args){
          OutClass out = new OutClass();
          InnerClass inner_1 = out.getInnerClass(201,"chenssy");
          System.out.println(inner_1.getName());
          InnerClass inner_2 = out.getInnerClass(23,"chenssy");
           System.out.println(inner_2.getName());
      }
    }

实例

匿名内部类可以有不同的表现形式,下面用实例向大家展示一下:
继承式的匿名内部类:

    abstract class Car{
      public abstract void drive();
    }
    class Test{
        public static void main(String[] args){
            Car car = new Car(){
                public void drive(){
                    System.out.println("Driving another car!");
                }
            };
            car.drive();
        }
    
    }

输出结果:
Driving another Car!
引用变量不是应用Car对象,而是Car匿名子类的对象
  建立匿名内部类的关键点事重写父类的一个或多个方法.再强调一下,是重写的方法,而不是创建新的方法.因为用父类的引用不可能调用父类本身没有的方法,创建新的方法时多余的.
 
接口式的匿名内部类:

  interface Vehicle{
      public void drive();
  }
  class Test{
       public static void main(String[] args){
          Vehicle vehicle = new Vehicle(){
              public void drive(){
                System.out.println("Driving a car!");
              }
            }
            vehicle.drive();
      }
  }

输出结果:
Driving a car!
上面的代码很怪,好像是在实例化一个接口.事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类.而且只能实现一个接口.

 //参数是的匿名内部类:
  abstract class Bar{
      void doStuff(Foo f){}
  }
  class BarOne extends Bar{
      void doStuff(Foo f){}
  }
  interface Foo{
      void foo();
  }
  class Test{
        static void go(){
            Bar b = new BarOne();
            b.doStuff(new Foo(){
              public void foo(){
                System.out.println("foofy");
              }
            })
        }
  }

 由上面的三个例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现.最常用的情况就是多线程的实现上,因为要实现多线程必须继承Thread类或是实现Runnable接口
Thread类的匿名内部类实现:

  public class Demo{
        public static void main(String[] args){
              Thread t = new Thread(){
                      public void run(){
                             for(int i = 1; i <= 5; i++){
                                    System.out.print(i +" ");
                              }
                       }
               };
              t.start();
        }
  }

Runnable接口的匿名内部类实现:

public class Demo{
    public static void main(String[] args){
          Runnable r = new Runnable(){
                public void run(){
                        for(int i = 1; i <= 5; i++){
                                System.out.print(i + " ");
                          }
                }
          };
        Thread t = new Thread(r);
        t.start();
    }

}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容