Première classe de voiture:
public class FastEngine extends Engine {
public FastEngine(int x, int y, double a, double b) {
super(x, y);
// (...)
}
// (...)
}
public class FastCar extends Car {
private final double a;
private final double b;
public FastCar(int x, int y, double a, double b) {
super(x, y);
this.a = a;
this.b = b;
}
@Override
protected Engine createEngine(int x, int y) {
// of course I can't use a and b here, they were not initialized yet :( :( :(
return new FastEngine(x, y /* I need a and b here too :( */);
}
}
3 Réponses :
Bien que je suis d'accord avec les commentaires que la question n'est pas bien formulée, je vous donnerai la solution. N'hésitez pas à ajouter des génériques pour le rendre plus beau. Puis dans votre sous-classe: P> public class FastEngine extends Engine {
public FastEngine(int x, int y, double a, double b) {
super(x, y);
// (...)
}
// (...)
}
public class FastCar extends Car {
static class FastCarConfig extends CarConfig {
double a;
double b;
FastCarConfig(int x, int y, double a, double b) {
super(x, y);
this.a = a;
this.b = b;
}
}
private final double a;
private final double b;
public FastCar(int x, int y, double a, double b) {
super(new FastCarConfig(x, y, a, b);
this.a = a;
this.b = b;
}
@Override
protected Engine createEngine(CarConfig config) {
if (config instanceof FastCarConfig) throw new IllegalStateException("You messed up!");
FastCarConfig c = (FastCarConfig) config;
return new FastEngine(c.x, c.y, c.a, c.b);
}
}
Je suggère de créer une usine de moteur. Rappelez-vous le " Responsabilité unique " Principe ( solide ).
Dans la vie réelle, vous ne construisez pas le moteur à l'intérieur de la voiture. Vous le faites séparément. Parfois sur une autre usine. Le moteur est installé dans la voiture sur la chaîne d'assemblage. P>
Cela vous donne plus de flexibilité à la fois - sur l'usine et dans le code. P>
aller plus loin, je suggère de mettre en œuvre un Modèle de constructeur - Si vous aurez plus de pièces installées dans la voiture. P>
Ps Ignorer "statique" S - Je viens de les ajouter à éviter les avertissements IDE. P>
public static void main(String[] args) {
Car car = new Car(EngineFactory.createEngine(1, 2));
Car fastCar = new FastCar(EngineFactory.createEngine(1, 2, 1d, 2d), 1d, 2d);
}
static class EngineFactory{
public static Engine createEngine(int x, int y){
return new Engine(x, y);
}
public static Engine createEngine(int x, int y, double a, double b){
return new FastEngine(x, y, a, b);
}
}
public static class Car {
private final Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
}
public static class FastCar extends Car {
private final double a;
private final double b;
public FastCar(Engine engine, double a, double b) {
super(engine);
this.a = a;
this.b = b;
}
}
public static class FastEngine extends Engine {
public FastEngine(int x, int y, double a, double b) {
super(x, y);
}
}
public static class Engine{
int x;
int y;
public Engine(int x, int y) {
this.x = x;
this.y = y;
}
}
Merci, c'est une autre solution, même si je pense que je préférerais, comme l'utilisateur de cette API, de créer la voiture sans avoir à créer ses pièces aussi, comme la réponse avec Carconfig. Imaginez si je devais créer une voiture et passer chaque composant de la voiture sur son contrat?
Dans ce cas, vous pouvez simplement créer une usine statique de voiture avec des méthodes simples. Ils appelleront la construction de voiture par des pièces. Cela sera transparent pour l'utilisateur de l'API, mais il ajoutera une flexibilité au code et permettra de créer des constructeurs et des types de voiture de base réutilisables.
Déplacez la conduction du moteur dans le constructeur de la voiture. Si la création des moteurs prend plus qu'un appel de constructeur, déplacez-la sur une fonction de constructeur statique.
class Engine {
private final int x;
private final int y;
Engine(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Car {
private final Engine engine;
public Car(int x, int y) {
this(new Engine(x, y));
}
Car(Engine engine) {
this.engine = engine;
}
}
public class FastEngine extends Engine {
private final double a;
private final double b;
FastEngine(int x, int y, double a, double b) {
super(x, y);
this.a = a;
this.b = b;
}
}
public class FastCar extends Car {
public FastCar(int x, int y, double a, double b) {
super(new FastEngine(x, y, a, b));
}
}
Beau, bien que je préfère la solution Carconfig, je n'ai donc pas besoin d'instancier le type de moteur à l'extérieur. Le constructeur peut également faire quelque chose de nécessaire pour l'initialisation du moteur. Mais votre solution est belle quand même! Qu'avez-vous pensé à la solution CarConfig de Chris? Et s'il vous plaît voter la question!
Si CARCONFIG est un concept utile dans votre domaine, alors par tous les moyens. Mais si c'est juste là pour résoudre ce problème, j'essaierais d'éviter d'introduire une abstraction inutile. De plus, j'aimerais éviter tout ce qui implique une "instance de", donc à tout le moins j'ajouterais un paramètre de type à la voiture afin que chaque voiture puisse spécifier son type de moteur.
@shmosel " Je ne peux pas utiliser A et B ici, ils n'étaient pas encore initialisés ... Quoi? Pourquoi pas? I>" - Si vous n'avez pas vu cela, nous avons un problème: P
@Cyrusleung vous avez ce mal malheureusement :(
Je vois maintenant. Ce n'est jamais une bonne idée d'appeler des méthodes d'instance à partir d'un constructeur. Envisager de construire le moteur à l'extérieur.
@shmosel d'accord, mais malheureusement, le moteur doit être construit dans le constructeur. I ne peut pas b> avoir une méthode Nowcreateengine () que j'appellerais après la création de la voiture: /
Pourquoi? Quelles sont les exigences exactement?
Je suis d'accord avec Shmosel. Ne construisez pas votre moteur à l'aide d'une méthode d'instance à partir du constructeur. Cela serait mieux résolu avec une injection de dépendance. Il suffit d'injecter le moteur que vous voulez dans votre constructeur.
Je pense que c'est un cas simple de xyproblem.info . Dites-nous quel problème vous essayez de résoudre plutôt qu'un exemple artificiel et nous pourrions peut-être vous aider davantage.
@Josh, c'est certainement la mauvaise façon d'agir sur ce site. Je vois que vous êtes nouveau contributeur, je ne vais donc pas vous signaler pour cela cette fois-ci, mais vous devez être conscient de lorsque les gens demandent des informations de clarification. Votre problème est simplement résolu en faisant ce que nous vous avons déjà dit de faire. Maintenant, si votre problème est en réalité un problème différent et que vous ne pouvez pas être résolu de cette façon, vous devez modifier votre question pour clarifier.
Voilà comment le code que je travaille semble ... Je ne peux pas changer le monde pour vous les gars, je suis désolé.
Vous n'avez pas expliqué pourquoi i> le code est comme ça. Peu importe que c'est à quoi ressemble actuellement. C'est une mauvaise idée. Nous ne pouvons pas vous aider avec une bonne solution si vous ne nous donnez pas plus d'informations.
Josh, je vais vous référer à ce document . Allez-y, lisez-le, pensez-y, puis revenez ici et travaillez avec nous.