java类实现自己内部接口是不允许的

java类继承或者实现自己内部的抽象类或者接口是不允许的

https://gcc.gnu.org/legacy-ml/gcc-patches/2001-04/msg01330.html

比如:

class A extend A.B{
      static class B{
            void fun(){};
        }
}

会报错:

Cyclic inheritance involving 'com.xxx.xxx.A'

意思就是循环调用,B的存在需要A的存在(因为B是A的内部类),而A的存在又需要B的存在(因为A继承B),这时编译器就不知道先编译谁了,就好像是让计算机去解决“先有鸡还是先有蛋”的问题,它会很懵逼!

上述这样写的目的:A想复用或者扩展B中的fun函数!

解决方案:

1.内部类改成外部类,使用继承(A可以直接调用B中的fun或者重写fun)

class B{ void fun(){};}
class A extend B{
      
}

2.使用组合类(A持有B的对象引用,A就可以直接调用B中的fun或者自己扩展)

package com.klx.rvdemo;

public class A{
    //
    class B{
        void fun(){};// B的fun函数
    }
    //
    B b;
    public A(B b){// 通过构造函数向A传入B引用
        this.b = b;
    }
    // A自己的fun函数
    void fun(){
        b.fun();// 调用了B的fun函数
    }
    
}

3.方式2可以发现A,B的fun函数名都一样,可以把相同函数变为接口(接口的所有实现类都必须实现接口里的函数)

package com.klx.rvdemo;

interface I{
    void fun();
}

public class A implements I{
    //
    class B implements I{

        @Override
        public void fun() {
            
        }
    }
    //
    I i;
    public A(I i){
        this.i = i;
    }
    
    @Override
    public void fun() {
        i.fun();
    }

}

4.发现方式3可以直接把A中内部类B删除了,没有影响(A依赖接口I而不再是依赖B,以后传递给A的就是I的实现类引用)

package com.klx.rvdemo;

interface I{
    void fun();
}

public class A implements I{
    I i;
    public A(I i){
        this.i = i;
    }

    @Override
    public void fun() {
        i.fun();
    }

}

5.当使用方式4的时候,发现给A构造函数传递I的实现类引用的时候可以用lambda表达式,直接传了个函数进去。

package com.klx.rvdemo;

interface I{
    void fun();
}

public class A implements I{
    I i;
    public A(I i){
        this.i = i;
    }

    @Override
    public void fun() {
        i.fun();
    }
    // test 
    public static void main(String[] args) {
        I i = new A(() -> {
            System.out.println("this is B fun");
        });
        i.fun();
    }

}

上面分析过程可总结为:

1.面向对象编程

2.使用继承

3.使用组合

4.面向接口编程

5.函数式编程

end

猜你喜欢

转载自blog.csdn.net/qq_17441227/article/details/109463064