J'ai appris le C # au cours des six derniers mois environ et je suis maintenant plongé dans Java. Ma question concerne la création d'instances (dans l'une ou l'autre langue, vraiment) et c'est plus: je me demande pourquoi ils l'ont fait de cette façon. Prenez cet exemple
Person Bob = new Person();
Y a-t-il une raison pour laquelle l'objet est spécifié deux fois? Y en aurait-il jamais something_else Bob = new Person()
?
Il semblerait que si je suivais la convention, ce serait plutôt:
int XIsAnInt;
Person BobIsAPerson;
Ou peut-être l'un d'eux:
Person() Bob;
new Person Bob;
new Person() Bob;
Bob = new Person();
Je suppose que je suis curieux de savoir s'il y a une meilleure réponse que "c'est juste la façon dont cela se fait".
java
c#
object-oriented
Jason Wohlgemuth
la source
la source
LivingThing
? Tu pourrais écrireLivingThing lt = new Person()
. Recherchez l' héritage et les interfaces.Person Bob
déclare une variable de type "référence àPerson
" appeléeBob
.new Person()
crée unPerson
objet. Les références, les variables et les objets sont trois choses différentes!var bob = new Person();
?Person Bob();
est possible en C ++ et signifie presque la même chose quePerson Bob = Person();
Réponses:
Oui, à cause de l'héritage. Si:
Alors:
Bob est aussi une personne, et par golly, il ne veut pas être traité différemment des autres.
De plus, nous pourrions doter Bob de super pouvoirs:
Et donc, par golly, il ne supportera pas d'être traité différemment de tout autre modérateur. Et il aime se faufiler autour du forum pour garder tout le monde en ligne tout en incognito:
Puis quand il trouve une mauvaise première affiche, il jette sa cape d'invisibilité et bondit.
Et puis il peut agir tout innocent et tout ça après:
la source
enum
.Prenons votre première ligne de code et examinons-la.
Le premier
Person
est une spécification de type. En C #, on peut se passer de cela en disant simplementet le compilateur déduira le type de la variable Bob à partir de l'appel du constructeur
Person()
.Mais vous voudrez peut-être écrire quelque chose comme ceci:
Lorsque vous ne remplissez pas l'intégralité du contrat API de Person, mais uniquement le contrat spécifié par l'interface
IPerson
.la source
IPerson
exemple dans mon code pour m'assurer de ne pas utiliser accidentellement de méthodes privées lorsque j'écris du code qui devrait être copié / collé dans une autreIPerson
implémentation.internal
?private
est significatif: les méthodes d'usine qui font partie de la classe en cours d'instanciation. Dans ma situation, l'accès aux valeurs privées devrait être l'exception et non la norme. Je travaille sur du code qui va me survivre longtemps. Si je le fais de cette façon, non seulement il est peu probable que j'utilise moi-même des méthodes privées, mais lorsque le prochain développeur copie / colle ceci quelques dizaines d'endroits et que le développeur les copie ensuite, cela diminue les chances que quelqu'un voit une opportunité de utiliser des méthodes privées comme comportement "normal".Cette syntaxe est à peu près un héritage de C ++, qui, en passant, a les deux:
et
Le premier pour créer un objet dans la portée actuelle, le second pour créer un pointeur vers un objet dynamique.
Vous pouvez certainement avoir
something_else Bob = new Person()
Vous faites deux choses différentes ici, en indiquant le type de la variable locale
nums
et vous dites que vous voulez créer un nouvel objet du type 'List' et le mettre là.C # est en quelque sorte d'accord avec vous, car la plupart du temps le type de la variable est identique à ce que vous y mettez donc:
Dans certaines langues, vous faites de votre mieux pour éviter d'indiquer les types de variables comme dans F # :
la source
new std::pair<int, char>()
, les membresfirst
etsecond
la paire ont une durée de stockage automatique, mais ils sont probablement alloués sur le tas (en tant que membres de l'objet dynamic-storage-durationpair
).Il y a une énorme différence entre
int x
etPerson bob
. Unint
est unint
est unint
et il doit toujours être unint
et ne peut jamais être autre chose qu'unint
. Même si vous n'initialisez pas leint
lorsque vous le déclarez (int x;
), c'est toujours unint
ensemble à la valeur par défaut.Person bob
Cependant, lorsque vous déclarez , il y a une grande flexibilité quant à ce à quoi le nombob
pourrait réellement faire référence à un moment donné. Elle pourrait faire référence à unePerson
, ou elle pourrait se référer à une autre classe, par exempleProgrammer
, dérivée dePerson
; ça pourrait même êtrenull
, ne faisant référence à aucun objet.Par exemple:
Les concepteurs de langage auraient certainement pu créer une syntaxe alternative qui aurait accompli la même chose que
Person carol = new Person()
dans moins de symboles, mais ils auraient quand même dû autoriserPerson carol = new Person()
(ou rendre une règle étrange rendant ce particulier des quatre exemples ci-dessus illégal). Ils étaient plus soucieux de garder le langage "simple" que d'écrire du code extrêmement concis. Cela a peut-être influencé leur décision de ne pas fournir la syntaxe alternative la plus courte, mais en tout cas, ce n'était pas nécessaire et ils ne l'ont pas fournie.la source
Les deux déclarations peuvent être différentes mais sont souvent les mêmes. Un modèle courant et recommandé en Java ressemble à ceci:
Ces variables
list
etmap
sont déclarées à l'aide des interfacesList
etMap
tandis que le code instancie des implémentations spécifiques. De cette façon, le reste du code ne dépend que des interfaces et il est facile de choisir une classe d'implémentation différente à instancier, commeTreeMap
, car le reste du code ne peut dépendre d'aucune partie de l'HashMap
API qui se trouve en dehors de l'Map
interface.Un autre exemple où les deux types diffèrent est dans une méthode d'usine qui sélectionne une sous-classe spécifique à instancier, puis la renvoie comme type de base afin que l'appelant n'ait pas besoin d'être au courant des détails d'implémentation, par exemple un choix de "politique".
L'inférence de type peut corriger la redondance du code source. Par exemple en Java
va construire le bon type de liste grâce à l'inférence de type et à la déclaration
Dans certains langages, l'inférence de type va plus loin, par exemple en C ++
la source
bob
, nonBob
. Cela évite beaucoup d'ambiguïté, par exemple package.Class vs Class.variable.clazz
.clazz
est utilisé carclass
est un mot-clé et ne peut donc pas être utilisé comme identifiant.Class
est un identifiant parfaitement valide.cLaSs
,cLASS
etcLASs
.Dans les mots du profane:
var = new Process()
vous ne déclarez pas la variable en premier.la source
Il s'agit également du niveau de contrôle sur ce qui se passe. Si la déclaration d'un objet / variable appelle automatiquement un constructeur, par exemple, si
était automatiquement le même que
alors vous ne pourriez jamais utiliser (par exemple) des méthodes d'usine statiques pour instancier des objets plutôt que des constructeurs par défaut, c'est-à-dire qu'il y a des moments où vous ne voulez pas appeler un constructeur pour une nouvelle instance d'objet.
Cet exemple est expliqué dans Joshua Bloch 's Effective Java (Item 1 assez ironiquement!)
la source