Aprendí C # en el transcurso de los últimos seis meses más o menos y ahora estoy profundizando en Java. Mi pregunta es sobre la creación de instancias (en cualquier idioma, realmente) y es más de: Me pregunto por qué lo hicieron de esa manera. Toma este ejemplo
Person Bob = new Person();
¿Hay alguna razón por la que el objeto se especifica dos veces? ¿Habría alguna vez unsomething_else Bob = new Person()
?
Parecería que si siguiera la convención sería más como:
int XIsAnInt;
Person BobIsAPerson;
O tal vez uno de estos:
Person() Bob;
new Person Bob;
new Person() Bob;
Bob = new Person();
Supongo que tengo curiosidad si hay una respuesta mejor que "así es como se hace".
java
c#
object-oriented
Jason Wohlgemuth
fuente
fuente
LivingThing
? Se puede escribirLivingThing lt = new Person()
. Busque herencia e interfaces.Person Bob
declara una variable de tipo "referencia aPerson
" llamadaBob
.new Person()
crea unPerson
objeto ¡Las referencias, variables y objetos son tres cosas diferentes!var bob = new Person();
?Person Bob();
es posible en C ++ y significa casi lo mismo quePerson Bob = Person();
Respuestas:
Sí, por herencia. Si:
Luego:
Bob también es una persona y, por Dios, no quiere ser tratado de manera diferente a los demás.
Además, podríamos dotar a Bob de superpoderes:
Y así, por Dios, no tolerará ser tratado de manera diferente a cualquier otro moderador. Y a él le gusta escabullirse por el foro para mantener a todos en línea mientras está de incógnito:
Luego, cuando encuentra un pobre primer póster, se quita su capa de invisibilidad y salta.
Y luego puede actuar inocente y todo eso después:
fuente
enum
.Tomemos su primera línea de código y examínelo.
El primero
Person
es una especificación de tipo. En C #, podemos prescindir de esto simplemente diciendoy el compilador inferirá el tipo de la variable Bob a partir de la llamada del constructor
Person()
.Pero es posible que desee escribir algo como esto:
Donde no está cumpliendo todo el contrato API de Persona, sino solo el contrato especificado por la interfaz
IPerson
.fuente
IPerson
ejemplo en mi código para asegurarme de no usar accidentalmente ningún método privado cuando escribo código que debería ser copiable / pegado a otraIPerson
implementación.internal
?private
es significativo: los métodos de fábrica que forman parte de la clase que se instancia. En mi situación, el acceso a valores privados debería ser la excepción, no la norma. Trabajo en código que me va a sobrevivir mucho tiempo. Si lo hago de esta manera, no solo es improbable que use métodos privados yo mismo, sino que cuando el próximo desarrollador copie / pegue esto unas pocas docenas de lugares y el desarrollador luego los copie, disminuye las probabilidades de que alguien vea la oportunidad de utilizar métodos privados como comportamiento "normal".Esta sintaxis es más o menos un legado de C ++, que, por cierto, tiene ambas:
y
El primero para crear un objeto dentro del alcance actual, el segundo para crear un puntero a un objeto dinámico.
Definitivamente puedes tener
something_else Bob = new Person()
Aquí está haciendo dos cosas diferentes, indicando el tipo de la variable local
nums
y dice que desea crear un nuevo objeto del tipo 'Lista' y ponerlo allí.C # está de acuerdo con usted, porque la mayoría de las veces el tipo de la variable es idéntico a lo que ingresa, por lo tanto:
En algunos idiomas, hace todo lo posible para evitar indicar los tipos de variables como en F # :
fuente
new std::pair<int, char>()
, entonces los miembrosfirst
ysecond
el par tienen una duración de almacenamiento automática, pero probablemente se asignan en el montón (como miembros delpair
objeto de duración de almacenamiento dinámico ).Hay una gran diferencia entre
int x
yPerson bob
. Unint
es unint
es unint
y siempre debe ser unint
y nunca puede ser otra cosa que unint
. Incluso si no inicializaint
cuando lo declara (int x;
), sigue siendo unint
conjunto con el valor predeterminado.Person bob
Sin embargo, cuando declaras , hay una gran flexibilidad en cuanto a lo que el nombrebob
podría referirse en un momento dado. Podría referirse a aPerson
, o podría referirse a alguna otra clase, por ejemploProgrammer
, derivada dePerson
; incluso podría sernull
, refiriéndose a ningún objeto en absoluto.Por ejemplo:
Los diseñadores de lenguaje ciertamente podrían haber hecho una sintaxis alternativa que hubiera logrado lo mismo que
Person carol = new Person()
en menos símbolos, pero aún así tendrían que permitirPerson carol = new Person()
(o hacer alguna regla extraña que haga que ese particular en particular de los cuatro ejemplos anteriores sea ilegal). Estaban más preocupados por mantener el lenguaje "simple" que por escribir código extremadamente conciso. Eso puede haber influido en su decisión de no proporcionar la sintaxis alternativa más corta, pero en cualquier caso, no fue necesario y no lo proporcionaron.fuente
Las dos declaraciones pueden ser diferentes, pero a menudo son las mismas. Un patrón común recomendado en Java se ve así:
Estas variables
list
ymap
se declaran utilizando las interfacesList
yMap
mientras el código crea instancias específicas. De esta manera, el resto del código solo depende de las interfaces y es fácil elegir una clase de implementación diferente para instanciarTreeMap
, ya que el resto del código no puede depender de ninguna parte de laHashMap
API que esté fuera de laMap
interfaz.Otro ejemplo en el que los dos tipos difieren es en un método de fábrica que selecciona una subclase específica para instanciar, luego la devuelve como el tipo base para que la persona que llama no necesite conocer los detalles de implementación, por ejemplo, una opción de "política".
La inferencia de tipos puede corregir la redundancia del código fuente. Ej. En Java
construirá el tipo correcto de Lista gracias a la inferencia de tipos y la declaración
En algunos idiomas, la inferencia de tipos va más allá, por ejemplo, en C ++
fuente
bob
, noBob
. Esto evita mucha ambigüedad, por ejemplo, package.Class vs. Class.variable.clazz
.clazz
se usa porqueclass
es una palabra clave, por lo que no se puede usar como identificador.Class
Es un identificador perfectamente válido.cLaSs
,cLASS
ycLASs
.En palabras simples:
var = new Process()
no declara la variable primero.fuente
También se trata del nivel de control sobre lo que está sucediendo. Si la declaración de un objeto / variable llama automáticamente a un constructor, por ejemplo, si
era automáticamente lo mismo que
entonces nunca podría usar (por ejemplo) métodos estáticos de fábrica para crear instancias de objetos en lugar de constructores predeterminados, es decir, hay momentos en los que no desea llamar a un constructor para una nueva instancia de objeto.
En este ejemplo se explica en Joshua Bloch 's Effective Java (artículo 1 irónicamente!)
fuente