如何在java中为可选继承建模

pw9qyyiw  于 2021-07-05  发布在  Java
关注(0)|答案(3)|浏览(246)

有没有一种方法可以像下面的例子中描述的那样实现可选继承?
从这个开始说:

注意:可以有4个以上的子类。
现在有一个可选的功能,称为“自主传输”,如这里所示。

选项1:如上图所示,我可以让所有子类从“自治传输”继承,但我不希望这样。比如说,不可能有一辆自主的火车。
选项2:没有严格的“autonomous transport”,但是根据需要有单独的类继承(可以是接口),比如“car”、“autonomous car”、“truck”、“autonomous truck”。但不是一个有吸引力的选择,因为有超过4个儿童班
选项3:可能的话,我可以使用依赖注入并在需要的地方注入“自治”功能,但是我不能添加任何框架,比如dagger等等。
有没有其他方法,可以用java干净地完成?基本上,如果“train”不能是自治的,我不希望有任何相关的业务逻辑。

flseospp

flseospp1#

如果自治是一个可选功能,那么它实际上并不是它所有子类的一个广义属性。
在我看来,这将是4个抽象类 AbstractCar , AbstractTruck 然后你可以有两个具体的抽象类的实现,比如 AutonomousCar 以及 NonAutonomousCar . 一个是自主的,另一个不是。
您可以为自治类提供一个标记接口,称为 IAutonomousTransport 当然,上面假设您不需要一个名为 isAutonomous 并在此基础上处理您的功能。但这种方法不会是多态的。

ny6fqffe

ny6fqffe2#

你应该在这里使用装饰图案:

public interface Transport {
    void foo();
}

public class AutonomousTransport implements Transport {
    public void foo() {
        // autonomous transport implementation
    }
}

public class Car implements Transport {
    private final Transport delegate;

    public Car(Transport delegate) {
        this.delegate delegate;
    }

    public void foo() {
        if(delegate == null)
            // car transport implementation
        else
            delegate.foo();
    }

}

p、 这个片段向您展示了一个简单的解决方案。它可能是这种模式的许多变体。
选项1:如上图所示,我可以让所有子类从“自治传输”继承,但我不希望这样。比如说,不可能有一辆自主的火车。
考虑替换 inheritancedelegation . 在大多数情况下,授权更可取。
选项2:没有严格的“autonomous transport”,但是根据需要有单独的类继承(可以是接口),比如“car”、“autonomous car”、“truck”、“autonomous truck”。但不是一个有吸引力的选择,因为有超过4个儿童班 Autonomous Transport 在我看来是行为,而不是财产。我确信,它不应该在 Transport 等级制度。
选项3:可能的话,我可以使用依赖注入并在需要的地方注入“自治”功能,但是我不能添加任何框架,比如dagger等等。
双亲注射是一种模式,但不是Spring或匕首那样的框架。如果您的类包含到另一个类的链接(通过构造函数或setter并不重要),事实上这已经是di了。

a64a0gku

a64a0gku3#

保持简单:
方案1

abstract class Transport {
   foo();
} 

abstract class AutomonousTransport extends Transport {
   bar();
}

class Car extends AutonomousTransport {
   // inherits foo and bar
}

class Train extends Transport {
   //inherits only foo(), which is ok, since Train is still a transport 
}

使用这种方法,您必须决定从哪个类继承,以便获得所需的功能。
这种方法的潜在缺点是,如果您有许多这样的不同功能(在java中,您只能从一个类进行扩展)。
要解决这个问题,如果您只继承功能(行为)而不继承状态,请考虑使用带有默认方法的接口,而不是抽象类。这有点像其他语言中的特征,但有一些限制:

interface Transport {
   default foo () {...} 
}

interface AutonomousTransport extends Transport {
   default bar() {}
}
interface WheelSupportTransport extends Transport {
   default rotateWheelLeft() {...}
   default rotateWheelRight() {...}
}

class Car implements AutomonousTransport, WheelSupportTransport  {

}

class Train implements Transport {...}

方案2

abstract class Transport {
   foo() 
}

final class AutonomousStuff { // final to prohibit inheritance from it
   bar()
}

class Car extends Transport {
   AutonomousStuff autonomousStuff;
}

class Train extends Transport {
   // only foo
}

这种方法基于“重组合轻继承”的思想。将行为作为内部数据字段添加到所需类中,并通过此字段获得对所需方法集(功能)的访问权限。
方案3

abstract class Transport {
   foo()
}

abstract class AutonomousCapable extends Transport {
    private final Transport transport;
    public AutonomouseCapable(Transport transport) {
       this.transport  =  transport;
    }
    bar()

    foo() {
        transport.foo();
    }

}

class Car extends Transport {}

class Train extends Transport {}

创建汽车时,使用 new AutonomousCapable(new Car()) 这遵循了“decorator”(又称 Package 器)模式的思想。您可以在运行时用一组额外的行为来“装饰”对象(汽车)。

相关问题