Java内部类

一、定义

1、即在一个类的内部定义的另一个类,内部类能直接访问外部内的所有变量,即可与外部类链接保持通信;内部类提供了某种进入其外部类的容器。
2、使用内部类的一大原因是:内部类能独立地继承自一个接口的实现,而无论外部类是否已经继承,对于内部类都没有影响。这间接实现了继承多个类。
3、内部类可以在一个类、方法等任意作用域内定义
4、在另一个类里实例一个类的非静态内部类使用.new。拥有外部类对象之前是不可能创建内部类对象的,所以需要先实例外部类。如果内部类是静态类,则和普通的静态类一样,可以直接调用。
5、接口中的内部类, 接口中可以放置内部类,接口中的任何类都自动是public static的,所以相当于放置了一个static公共方法;
6、内部类是面向对象的闭包
7、内部类可以被继承,继承时不用继承外部类;
8、内部类被编译后会生成一个独立的.class文件,命名规则为:外部类的名字加上$,再加上内部类的名字。如果内部类是匿名的,编译器会简单的生成一个数字作为其标识符。
示例:

public class StudyTest {
    StudyTest(){
      System.out.println("construct StudyTest");
    }
    private String study = "study";
    
    public class InnerClass{
      public StudyTest outClass(){
          System.out.println(study);
          return StudyTest.this;  //使用.this直接调用当前类的父类
      }
    }

    public static void main(String[] args) {
          InnerClass innerClass = new StudyTest().new InnerClass(); //实例内部类
          innerClass.outClass();
    }
}

运行结果:

construct StudyTest
study

二、应用

1、内部类用于隐藏实现细节示例

接口与调用:

public interface StudyInterface {
    String getValue();
}
public class MainClass {
    public static void main(String[] args) {
        StudyInterface studyInterface = new StudyTest().instance();
        System.out.println(studyInterface.getValue());
    }
}

实现:

public class StudyTest {
    StudyTest(){
      System.out.println("construct StudyTest");
    }
    private String study = "study";

    //此内部类对外不可见,不可实例不可继承.
    private class InnerClass implements StudyInterface{
        @Override
        public String getValue() {
            return study;
        }
    }
    public StudyInterface instance(){
        return new InnerClass();
    }
}

通过这种方式可以完全阻止任何依赖于类型的编码,并且完全隐藏了实现细节。从调用方的角度看,由于不能访问任何新增加的、原本不属于公共接口的方法,所以扩展接口是没有价值的。

2、匿名内部类

public class StudyTest {
    private String name = "study";
    public String getName(){return this.name;}
}
public class MainClass {
    public StudyTest studyTestPlus(){
        return new StudyTest(){
            private String nameplus = "studyTestPlus";
            public String getName(){return  nameplus;}
        }; //注意此处有分号,不能省略
    }
    public static void main(String[] args) {
        StudyTest studyTest = new MainClass().studyTestPlus();
        System.out.println(studyTest.getName());
 }
//----------studyTestPlus()处相当于对StudyTest类进行了继承拓展,效果和下边的代码一样:----------
    public class StudyTestPlus extends StudyTest{
        private String nameplus = "studyTestPlus";
        public String getName(){return  nameplus;}
    }
    public StudyTest studyTestPlus(){
        return new StudyTestPlus();
    }

匿名内部类既可以扩展类,也可以实现接口,但不能两者兼备,如果实现接口也只能实现一个。

3、匿名内部类与工厂模式结合

public interface Service{ void printName();}
public interface ServiceFactory{Service getService();}
public class Factory{
    public static void serviceConsumer(ServiceFactory factory){
        factory.getService().printName();
    }
}

public class Implements1 implements Service{
    public void printName(){System.out.println("Implements1");}
    public static ServiceFactory factory =new ServiceFactory() {
        public Service getService() {
            return new Implements1();
        }
    };
}
public class Implements2 implements Service{ 
    public static ServiceFactory factory =new ServiceFactory() {
        public Service getService() {
            return new Implements2();
        }
    };
}
//使用
public static void main(String[] args) {
    Factory.serviceConsumer(Implements1.factory);
    Factory.serviceConsumer(Implements2.factory);
}

 

posted @ 2021-01-20 21:58  覆手为云p  阅读(112)  评论(0编辑  收藏  举报
停止精灵球