Comment puis-je la force d'un Constructeur à être défini dans toutes les classes de ma classe abstraite
J'ai une classe abstraite Une qui définissent des méthodes abstraites. Cela signifie que, pour qu'une classe instanciable, tous la méthode abstraite doivent être mises en œuvre.
J'aimerais que tous mes sous-classes pour implémenter un constructeur avec 2 ints en tant que paramètres.
Déclarer un constructeur défaites mon but, je veux le constructeur défini dans les sous-classes et je ne sais rien à propos de la mise en œuvre. De plus je ne peut pas déclarer un constructeur comme étant abstraite;
Est-il un moyen de faire cela ?
Exemple de ce que je veux:
Permet de dire que je suis la définition de l'API d'une classe Matrix. Dans mon problème, la Matrice ne peut pas modifier leurs dimensions.
Pour une Matrice à créer, j'ai besoin de fournir sa taille.
Donc, je veux que tous mes réalisateurs de fournir le constructeur avec la taille comme un paramètre. Ce constructeur est motivée par le problème, et non pas par une mise en œuvre préoccupation. La mise en œuvre peut faire ce qu'il veut avec ces, à condition que toutes les sémantiques des méthodes sont conservés.
Disons que je veux fournir une base de mise en œuvre de la invert()
méthode dans ma classe abstraite. Cette méthode permet de créer une nouvelle matrice avec this
inversé dimensions. Plus précisément, comme il est défini dans la classe abstraite, il va créer une nouvelle instance de la même classe que this
, à l'aide d'un constructeur qui prend deux entiers. Comme il ne sait pas à l'instance, il va utiliser la réflexion (getDefinedConstructor) et je veux un moyen de garantie que je vais le faire et que ce sera significatif pour la mise en œuvre.
OriginalL'auteur dodecaplex | 2010-07-02
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas forcer un particulier de la signature du constructeur de votre sous-classe - mais vous peut le forcer à passer par un constructeur dans votre classe abstraite en prenant deux entiers. Les sous-classes pourrait appel de constructeur à partir d'un constructeur sans paramètre, en passant constantes, par exemple. Qui est le plus proche que vous pouvez trouver.
En outre, comme vous le dites, vous ne savez rien à propos de la mise en œuvre - alors, comment savez-vous qu'il est approprié pour eux d'avoir un constructeur qui demande deux nombres entiers? Que faire si l'un d'eux a besoin d'une Chaîne de caractères? Ou peut-être il en a de sens pour elle d'utiliser une constante pour l'un de ces entiers.
Quelle est la plus grande image ici - pourquoi voulez-vous forcer un particulier de la signature du constructeur de votre sous-classes? (Comme je l'ai dit, vous ne pouvez pas réellement ne cela, mais si vous expliquez pourquoi vous le voulez, une solution pourrait présenter de lui-même.)
Une option est d'avoir une interface pour une usine:
Puis chacun de vos sous-classes concrètes de
MyClass
aurait aussi besoin d'une usine qui a su créer une instance donnée de deux nombres entiers. Il n'est pas très pratique si - et vous avez encore besoin de construire des instances de la usines elles-mêmes. Encore une fois, quelle est la situation réelle ici?Mais que faire si vous voulez créer un
FixedSizeMatrix
de mise en œuvre qui est toujours 10 x 10? Vous ne pouvez pas constructeurs polymorphically de toute façon, alors pourquoi êtes-vous essayer de limiter la mise en œuvre?Eh bien la mise en œuvre ne sera pas conforme à mon API... Si il a de bonnes raisons de le faire, alors, il fournira un zéro arg constructeur et un 2 args constructeur qui va lever une Exception si les arguments ne sont pas de 10x10. Cela signifie que je vais encore être en mesure de créer une Matrice vide de la même mise en œuvre et de la même taille (sans le savoir la mise en œuvre efficace), mais je vais obtenir une exception si j'essaie d'utiliser cette œuvre à des fins non 10x10 Matrices.
Je ne veux pas restreindre la mise en œuvre, mais à bien définir le contrat qu'il a à remplir. La seule chose, c'est pourquoi je ne devrais pas être en mesure d'inclure un constructeur dans le contrat ?
vous pouvez facilement déclarer un constructeur dans la classe abstraite qui a pris deux entiers, puis un non-arg constructeur de
FixedSizeMatrix
qui ressemblepublic FixedSizeMatrix() { super(10, 10); }
, comme Jon a dit. Les api sont de moins en moins sur les constructeurs (la façon dont vous construisez un objet) que sur les méthodes (comment vous utilisez un objet).OriginalL'auteur Jon Skeet
Vous pouvez essayer quelque chose comme ci-dessous. Le constructeur de levée d'une exception si la mise en œuvre de la classe ne possède pas de constructeur avec les arguments appropriés.
Que c'est stupide. Comparer OK et Mauvais. Les deux classes sont les mêmes, sauf que ça répond à vos besoins et passe donc à l'exécution des contrôles. Ainsi, l'application de l'exigence favorise la contre-productif le travail occupé.
Une meilleure solution serait une sorte d'Usine.
OriginalL'auteur emory
Si vous avez besoin de définir dans votre interface de la représentation interne que la mise en place de classes à utiliser, alors vous êtes juste de faire le mal. Veuillez aller lire à ce sujet l'encapsulation et l'abstraction de données.
Si votre résumé de la mise en œuvre s'appuie sur certains détails de mise en œuvre, alors qu'ils appartiennent à cette classe abstraite. Sens, la classe abstraite doit définir un constructeur qui permet d'initialiser l'état interne nécessaire pour permettre à l'abstraction des méthodes de travail.
Généralement, les constructeurs sont destinés à créer une instance d'une classe en fournissant certains détails de l'état initial de l'instance de l'objet. Cela ne signifie pas que l'instance en cours de construction devrait copier une référence à chaque argument, comme c'est souvent le cas dans la plupart des logiciels que je vois. Par conséquent, même si Java n'offre une construction pour forcer la mise en œuvre de certaines Constructeur de signatures sur les sous-classes, les sous-classes pourrait facilement jeter les arguments.
Ahh, un point, un grand exemple. Supposons que vous parlez d'un 2-dimensionnelle point. Bien, sûr, je peux utiliser une valeur x et y pour le représenter. Ou, je peux utiliser un radians et degrés de la valeur et une valeur de distance pour le représenter. Juste un exemple. Il pourrait y avoir d'autres façons. Vous ne pensez que vous savez comment on pourrait mettre en œuvre. De toute façon, par définition, si vous tentez d'appliquer une représentation vous n'êtes pas en utilisant l'abstraction de données.
OriginalL'auteur Tim Bender
Un peu de retard, mais...
Il suffit de créer un constructeur par défaut dans votre classe qui est toujours appelé comme super constructeur. Dans ce constructeur par défaut vous pouvez consulter tous les constructeurs avec la réflexion sur son propre objet de classe (qui n'est alors pas l'abstrait super classe mais le concret de la sous-classe). Si le constructeur vous souhaitez être mis en œuvre est manquant, jeter une exception d'exécution.
Je ne suis pas un grand ami de la réflexion, car il a le goût de piratage par la porte arrière, mais parfois ça aide...
Ont un coup d'oeil à cet exemple:
Et une classe de test:
Dans la fonction principale les objets de Gaga1 sera créé, mais la création de Gaga2 va lancer une exception d'exécution.
Mais vous ne pouvez pas être sûr que ce constructeur est appelé - vous ne pouvez même pas vous assurer qu'il est en train de faire les choses que vous voulez.
Ce test est utile uniquement si vous travaillez avec la réflexion.
OriginalL'auteur Abdullah
Ont la classe abstraite d'avoir une méthode abstraite qui prend ce que vous auriez des paramètres. Par exemple:
OriginalL'auteur yesennes