liujijiang

java学习笔记 --10-- 内部类

2020.03.29

内部类

在类里面的类

package com.company;

public class Main {
    public static void main(String[] args) {
	// write your code here
        
        Test1 test1 = new Test1();
        
        
    }
    
    static class Test1{
        public Test1(){
            System.out.println("Test1");
        }
    }
    
    class Test2{
        public Test2(){
            System.out.println("Test2");
        }
    }
}

链接到外部类

在内部类中可以使用外部类中的元素

package com.company;

public class Main {
    
    private int a;
    
    public static void main(String[] args) {
	// write your code here

        Test1 test1 = new Test1();
    }
    
    public void ppp(){
        System.out.println("ppp");
    }

    static class Test1{
        public Test1(){
            System.out.println("Test1");
        }
        
    }

    class Test2{
        public Test2(){
            System.out.println("Test2");
        }

        public void addA(){
            a++;
            ppp();
        }
    }
}

Test2使用了外部类中的成员a和方法add
即使a是private,内部类仍然可以访问他,就像是拥有它一样

其实是内部类秘密捕获了外部类的一个引用,通过引用调用外部类中的元素

.this 和 .new

内部类使用.this获取外部类的***对象***的引用
就是返回外部类的当前对象

package com.company;

public class Main {
    public static void main(String[] args) {
	// write your code here
        Main main = new Main();
        
        Test test = main.test();

        test.mm().ff();
    }

    public Test test(){
        return new Test();
    }

    public void ff(){
        System.out.println("ff");
    }

    class Test{
        public Test(){

        }
        public Main mm(){
            return Main.this;
        }
    }
}

内部类Test的mm方法返回的就是外部类的对象main
静态方法中不能直接对非静态的内部类初始化,可以使用外部类的一个方法对内部类初始化

.new:可以用来创建内部类的对象


package com.company;

public class Main {
    public static void main(String[] args) {
	// write your code here
        Main main = new Main();

        Test test =main.new Test();

        test.mm().ff();
    }

    public Test test(){
        return new Test();
    }

    public void ff(){
        System.out.println("ff");
    }

    class Test{
        public Test(){

        }
        public Main mm(){
            return Main.this;
        }
    }
}

使用 main.new 代替new 创建一个内部类对象

  • 非静态内部类的创建一定是需要先创建外部类的,因为非静态内部类隐含一个外部类的引用
  • 静态内部类不需要先创建外部类

匿名类在工厂模式中的使用

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void serviceConsumer(ServiceFactory factory){
        Service service = factory.getService();
        service.method1();
        service.method2();
    }

    public static void main(String [] args){
        serviceConsumer(Implemention1.factory());
    }
}

interface Service{
    void method1();
    void method2();
}

interface ServiceFactory{
    Service getService();
}

class Implemention1 implements Service{
    public Implemention1(){

    }

    public void method1(){
        System.out.println("method1 out");
    }

    public void method2(){
        System.out.println("method2 out");
    }

    public static ServiceFactory factory(){
        return new ServiceFactory() {
            @Override
            public Service getService() {
                return new Implemention1();
            }
        };
    }
}


嵌套类

如果你不希望内部类与外部类之间有联系,那么你可以把内部类声明为static(嵌套类)

  • 创建嵌套类对象不需要外部类的引用
  • 嵌套类不能使用外部类的非静态元素

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    static class InClass{
        public void mm(){
            System.out.println("mm");
        }
    }

    public static void main(String [] args){
        InClass inClass = new InClass();
        inClass.mm();
    }
}

像static方法一样,static内部类也是没有this的

接口内部类

interface Implemention{
    class InClass{
        private int a;
        public InClass(){
            a =1;
        }
    }
}

接口是不能有实现的代码的,但是可以把内部类放在接口中

为什么需要内部类

一个主要的原因:每个内部类都能独立的继承一个接口的实现,无论外围类是否继承了这个接口,对内部类没有影响

接口的两种实现:

package com.company;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){

        Implemention1.InClass implemention1 = new Implemention1.InClass();

        Implemention2 implemention2 = new OutClass();

        implemention1.mm();
        implemention2.mm();
    }

}

interface Implemention1{
    void mm();
    class InClass{
        public void mm(){
            System.out.println("mm");
        }
    }
}

interface Implemention2{
    void mm();
}
class OutClass implements Implemention2{
    @Override
    public void mm() {
        System.out.println("mm");
    }
}

第一种通过内部类实现了一个接口
第二种通过外部类实现一个接口
第一种的好处就是:这个接口是否有外部类对其进行实现,不影响内部类

未完。。。