使用继承将 'static' 代码与 'dynamic' 代码分开的更简洁的方法

Cleaner way of using inheritance to separate 'static' code from 'dynamic' code

(静态和动态是指代码是否容易更改的区别)

我目前遇到了一些奇怪的问题。我正在编写一个应用程序,其中涉及组件之间的一些复杂交互,在这些交互中很难跟踪代码流。为了简化这一点,我试图通过创建 'layers' 来构建代码,其中每一层都比它上面的层增加了功能。每层都包含在一个包中。我遇到以下问题:

考虑以下 2 类 及其具有增强功能的子类:

Class答:

package layer;
class A {
    B b;

    A() {
        b = new B();
    }

    void foo() {
        b.foo();
    }

    /* More A-class methods here */
}

Class乙:

package layer;
class B {
    void foo() {
        // Do something
    }

    /* More B-class methods here */
}

A 类:

package sublayer;
class ASub extends A {

    ASub() {
        super.b = new BSub(); // This needs a cast to compile
    }
}

B 类:

package sublayer;
class BSub extends B {
     @Override
     void foo() {
        // Do something with more functionality
     }
}

最后我只想实例化和修改类 ASub和BSub,能够使用super类 A和B的所有方法而不需要实际修改[=41中的代码=] A 和 B 本身。

如果我调用new ASub().foo(),我想要执行BSub 的重写foo() 而不是B 的foo()。当然我可以在ASub 中添加一个变量BSub bsub 并重写A 的foo()方法调用 bsub.foo(),但这并没有避免在 A 的构造函数中创建对象 b,这似乎是草率的编码。对此有什么想法吗?欢迎任何评论。

使用继承来提高可重用性是一个非常非常糟糕的主意。继承应始终由您试图描述的对象的性质驱动。您需要学习自己使用术语和抽象来问自己 "What is the nature of what I am trying to describe"。我的建议是学习一本关于领域驱动设计的书,例如或 Code Complete。还要考虑多态性和设计模式。

你的问题有点争议。对象创建和依赖注入是很多讨论的主题,也是各种框架和设计模式的核心焦点。

但我希望这是对您问题的一个简单回答,不是一般"what's the best way to create objects in Java?"

在下面的代码中,我将实例化 B 的责任移到了从 A(超类)构造函数调用的方法 (instantiateB()) 中。所以,当你想要子类化 A 时,你重写该方法而不是重写构造函数。

package com.matt.tester;

public class SE {

    static class A {
        B b;

        A() {
            instantiateB();
        }

        void instantiateB () {
            this.b = new B();
        }

        void foo() {
            b.foo();
        }

        /* More A-class methods here */
    }

    static class B {
        void foo() {
            System.out.println("Hellow from B.foo()!");
        }

        /* More B-class methods here */
    }
    static class ASub extends A {

        @Override
        void instantiateB() {
            this.b = new BSub();
        }
    }
    static class BSub extends B {
         @Override
         void foo() {
            System.out.println("Hellow from BSub.foo()!");
         }
    }

    public static void main(String[] args) {
        A a = new ASub();
        a.foo();
    }
}