Hasta ahora, hemos cubierto los conceptos básicos del lenguaje de programación Swift. Si siguió adelante, ahora debería tener una comprensión sólida de variables, constantes, funciones y cierres. Ahora es el momento de utilizar lo que hemos aprendido y aplicar ese conocimiento a las estructuras orientadas a objetos de Swift.
Para comprender los conceptos discutidos en este tutorial, es importante que tenga una comprensión básica de la programación orientada a objetos. Si no está familiarizado con las clases, los objetos y los métodos, le recomiendo que primero lea estos temas antes de continuar con este tutorial..
eBook: Programación Orientada a Objetos Con Swift
En esta lección, vamos a explorar los bloques de construcción fundamentales de la programación orientada a objetos en Swift, clases y estructuras. En Swift, las clases y las estructuras se sienten y se comportan de manera muy similar, pero hay una serie de diferencias clave que debe comprender para evitar las dificultades comunes..
En Objective-C, las clases y las estructuras son muy diferentes. Esto no es cierto para Swift. En Swift, por ejemplo, tanto las clases como las estructuras pueden tener propiedades y métodos. A diferencia de las estructuras en C, las estructuras en Swift pueden extenderse y también pueden ajustarse a los protocolos.
La pregunta obvia es: "¿Cuál es la diferencia entre clases y estructuras?" Volveremos a examinar esta pregunta más adelante en este tutorial. Primero exploremos cómo se ve una clase en Swift.
Antes de comenzar a trabajar con clases y estructuras, me gustaría aclarar algunos términos comunes en la programación orientada a objetos. Los términos clases, objetos, y instancias A menudo confunden a las personas nuevas con la programación orientada a objetos. Por lo tanto, es importante que sepa cómo Swift usa estos términos..
UNA clase es un plano o plantilla para una instancia de esa clase. El término "objeto" se usa a menudo para referirse a una instancia de una clase. En Swift, sin embargo, las clases y estructuras son muy similares, y por lo tanto es más fácil y menos confuso usar el término "instancia" para ambas clases y estructuras.
Anteriormente en esta serie, trabajamos con funciones. En el contexto de clases y estructuras, generalmente nos referimos a funciones como métodos. En otras palabras, los métodos son funciones que pertenecen a una clase o estructura particular. En el contexto de clases y estructuras, puede usar ambos términos indistintamente ya que cada método es una función.
Mojémonos los pies y definamos una clase. Arranca Xcode y crea un nuevo parque infantil. Quite los contenidos del patio de recreo y agregue la siguiente definición de clase.
clase Persona
los clase
palabra clave indica que estamos definiendo una clase llamada Persona. La implementación de la clase está envuelta en un par de llaves. A pesar de Persona
La clase no es muy útil en su forma actual, es una clase Swift adecuada y funcional..
Como en la mayoría de los otros lenguajes de programación orientados a objetos, una clase puede tener propiedades y métodos. En el ejemplo actualizado a continuación, definimos tres propiedades:
nombre de pila
, una propiedad variable de tipo Cuerda?
apellido
, una propiedad variable de tipo Cuerda?
lugar de nacimiento
: una propiedad constante de tipo Cuerda
class Person var firstName: String? var lastName: String? let birthPlace = "Belgium"
Como se ilustra en el ejemplo, definir propiedades en una definición de clase es similar a definir variables y constantes regulares. Usamos el var
palabra clave para definir una propiedad variable y la dejar
palabra clave para definir una propiedad constante.
Las propiedades anteriores también se conocen como propiedades almacenadas. Más adelante en esta serie, aprendemos sobre propiedades computadas. Como su nombre lo indica, las propiedades almacenadas son propiedades almacenadas por la instancia de la clase. Son similares a las propiedades en Objective-C.
Es importante tener en cuenta que cada propiedad almacenada debe tener un valor después de la inicialización o debe definirse como un tipo opcional. En el ejemplo anterior, damos la lugar de nacimiento
propiedad un valor inicial de "Bélgica"
. Esto le dice a Swift que la propiedad del lugar de nacimiento es de tipo Cuerda
. Más adelante en este artículo, echamos un vistazo a la inicialización con más detalle y exploramos cómo se relaciona con las propiedades de inicialización..
Aunque definimos la lugar de nacimiento
como una constante, es posible cambiar su valor durante la inicialización de un Persona
ejemplo. Una vez que la instancia ha sido inicializada, la lugar de nacimiento
la propiedad ya no se puede modificar ya que definimos la propiedad como una propiedad constante con el dejar
palabra clave.
Podemos agregar comportamiento o funcionalidad a una clase a través de funciones o métodos. En muchos lenguajes de programación., método se utiliza en lugar de función En el contexto de las clases e instancias. Definir un método es casi idéntico a definir una función. En el siguiente ejemplo, definimos la nombre completo()
método en el Persona
clase.
class Person var firstName: String? var lastName: String? let birthPlace = "Belgium" func fullName () -> String var parts: [String] = [] si let firstName = self.firstName parts + = [firstName] si let lastName = self.lastName parts + = [ lastName] return parts.joined (separator: "")
El método nombre completo()
Está anidado en la definición de la clase. No acepta parámetros y devuelve un Cuerda
. La implementación de la nombre completo()
El método es sencillo. A través del enlace opcional, que discutimos anteriormente en esta serie, accedemos a los valores almacenados en el nombre de pila
y apellido
propiedades.
Almacenamos el nombre y apellido de la Persona
Instalar en una matriz y unir las partes con un espacio. El motivo de esta implementación un tanto torpe debe ser obvio: el nombre y el apellido pueden estar en blanco, por lo que ambas propiedades son de tipo Cuerda?
.
Hemos definido una clase con algunas propiedades y un método. ¿Cómo creamos una instancia de la Persona
¿clase? Si está familiarizado con Objective-C, entonces le encantará la concisión del siguiente fragmento de código.
dejar que john = persona ()
La creación de una instancia de una clase es muy similar a invocar una función. Para crear una instancia, el nombre de la clase va seguido de un par de paréntesis, y el valor de retorno se asigna a una constante o variable.
En nuestro ejemplo, la constante. Juan
Ahora apunta a una instancia de la Persona
clase. ¿Significa esto que no podemos cambiar ninguna de sus propiedades? El siguiente ejemplo responde a esta pregunta..
john.firstName = "John" john.lastName = "Doe" john.birthPlace = "France"
Podemos acceder a las propiedades de una instancia utilizando la comodidad de la sintaxis de puntos. En el ejemplo, ponemos nombre de pila
a "Juan"
, apellido
a "Gama"
, y lugar de nacimiento
a "Francia"
. Antes de sacar conclusiones basadas en el ejemplo anterior, debemos comprobar si hay errores en el patio de recreo..
Ajuste nombre de pila
y apellido
No parece causar ningún problema. Pero asignando "Francia"
al lugar de nacimiento
La propiedad resulta en un error. La explicacion es simple.
Aunque Juan
Se declara como una constante, que no nos impide modificar la Persona
ejemplo. Sin embargo, hay una advertencia: solo las propiedades variables se pueden modificar después de inicializar una instancia. Las propiedades que se definen como constantes no se pueden modificar una vez que se asigna un valor.
Una propiedad constante se puede modificar durante la inicialización de una instancia. Mientras que la lugar de nacimiento
la propiedad no se puede cambiar una vez que Persona
Se crea una instancia, la clase no sería muy útil si solo pudiéramos instanciar Persona
Casos con un lugar de nacimiento de "Bélgica". Hagamos el Persona
clase un poco más flexible.
La inicialización es una fase en la vida útil de una instancia de una clase o estructura. Durante la inicialización, preparamos la instancia para su uso al rellenar sus propiedades con valores iniciales. La inicialización de una instancia se puede personalizar implementando un inicializador, un tipo especial de método. Vamos a definir un inicializador para el Persona
clase.
class Person var firstName: String? var lastName: String? let birthPlace = "Belgium" init () birthPlace = "France"…
Hemos definido un inicializador, pero nos encontramos con varios problemas. Echa un vistazo al error que el compilador nos lanza..
No solo el inicializador no tiene sentido, el compilador también nos advierte que no podemos modificar el valor de lugar de nacimiento
Propiedad ya que ya tiene un valor inicial. Podemos resolver el error eliminando el valor inicial de lugar de nacimiento
propiedad.
class Person var firstName: String? var lastName: String? let birthPlace: String init () birthPlace = "France"…
Tenga en cuenta que el nombre del inicializador, en eso()
, no está precedido por el función
palabra clave. A diferencia de los inicializadores en Objective-C, un inicializador en Swift no devuelve la instancia que se está inicializando.
Otro detalle importante es cómo configuramos el lugar de nacimiento
Propiedad con un valor inicial. Establecemos el lugar de nacimiento
propiedad utilizando el nombre de la propiedad, pero también está bien ser más explícito como este.
init () self.birthPlace = "France"
los yo
palabra clave se refiere a la instancia que se está inicializando. Esto significa que self.birthPlace
se refiere a lugar de nacimiento
Propiedad de la instancia. Podemos omitir yo
, como en el primer ejemplo, porque no hay confusión sobre a qué propiedad nos referimos. Sin embargo, este no es siempre el caso. Déjame explicarte a lo que me refiero.
El inicializador que definimos no es muy útil en este momento, y no resuelve el problema con el que empezamos: poder definir el lugar de nacimiento de una persona durante la inicialización.
En muchas situaciones, desea pasar los valores iniciales al inicializador para personalizar la instancia que está creando. Esto es posible creando un inicializador personalizado que acepte uno o más argumentos. En el siguiente ejemplo, creamos un inicializador personalizado que acepta un argumento, lugar de nacimiento
, de tipo Cuerda
.
init (birthPlace: String) self.birthPlace = birthPlace
Vale la pena señalar dos cosas. Primero, estamos obligados a acceder a la lugar de nacimiento
propiedad a través de self.birthPlace
para evitar ambigüedades ya que el nombre del parámetro local es igual a lugar de nacimiento
. En segundo lugar, aunque no hemos especificado un nombre de parámetro externo, Swift crea de forma predeterminada un nombre de parámetro externo que es igual al nombre del parámetro local.
En el siguiente ejemplo, instanciamos otra Persona
instancia invocando el inicializador personalizado que acabamos de definir.
let maxime = Person (birthPlace: "France") print (maxime.birthPlace)
Al pasar un valor para el lugar de nacimiento
parámetro al inicializador, podemos asignar un valor personalizado a la constante lugar de nacimiento
propiedad durante la inicialización.
Como en Objective-C, una clase o estructura puede tener múltiples inicializadores. En el siguiente ejemplo, creamos dos Persona
instancias. En la primera línea, usamos el inicializador por defecto. En la segunda línea, usamos el inicializador personalizado que definimos anteriormente.
dejar p1 = Persona () dejar p2 = Persona (birthPlace: "Francia")
Las estructuras son sorprendentemente similares a las clases, pero hay algunas diferencias clave. Empecemos definiendo una estructura básica..
struct Wallet var dollars: Int var cents: Int
A primera vista, la única diferencia es el uso del estructura
palabra clave en lugar de la clase
palabra clave. El ejemplo también nos muestra un enfoque alternativo para suministrar valores iniciales a propiedades. En lugar de establecer un valor inicial para cada propiedad, podemos asignar a las propiedades un valor inicial en el inicializador de la estructura. Swift no generará un error, ya que también inspecciona el inicializador para determinar el valor inicial y el tipo de cada propiedad.
Puede comenzar a preguntarse cuál es la diferencia entre clases y estructuras. A primera vista, se ven idénticos en forma y función, con la excepción de la clase
y estructura
palabras clave. Hay una serie de diferencias clave, aunque.
Las clases apoyan la herencia, mientras que las estructuras no lo hacen. El siguiente ejemplo lo ilustra. El patrón de diseño de herencia es indispensable en la programación orientada a objetos y, en Swift, es una diferencia clave entre clases y estructuras..
class Person var firstName: String? var lastName: String? let birthPlace: String init (birthPlace: String) self.birthPlace = birthPlace class Estudiante: Persona var school: String? let student = Student (birthPlace: "France")
En el ejemplo anterior, el Persona
clase es el padre o superclase de la Estudiante
clase. Esto significa que el Estudiante
clase hereda las propiedades y el comportamiento de la Persona
clase. La última línea ilustra esto. Inicializamos un Estudiante
instancia invocando el inicializador personalizado definido en el Persona
clase.
El siguiente concepto es probablemente el concepto más importante en Swift que aprenderá hoy, la diferencia entre tipos de valor y tipos de referencia. Las estructuras son tipos de valor, lo que significa que se pasan por valor. Un ejemplo ilustra mejor este concepto..
estructura Punto var x: Int var y: Int init (x: Int, y: Int) self.x = x self.y = y var point1 = Point (x: 0, y: 0) var point2 = point1 point1.x = 10 print (point1.x) // 10 print (point2.x) // 0
Definimos una estructura., Punto
, para encapsular los datos para almacenar una coordenada en un espacio bidimensional. Nosotros instanciamos punto 1
con X
igual a 0
y y
igual a 0
. Asignamos punto 1
a punto2
y establecer el X
coordenada de punto 1
a 10
. Si sacamos el X
Coordenadas de ambos puntos, descubrimos que no son iguales..
Las estructuras se pasan por valor, mientras que las clases se pasan por referencia. Si planea continuar trabajando con Swift, debe comprender la declaración anterior. Cuando asignamos punto 1
a punto2
, Swift creó una copia de punto 1
y asignado a punto2
. En otras palabras, punto 1
y punto2
cada punto a una instancia diferente de la Punto
estructura.
Repitamos ahora este ejercicio con la Persona
clase. En el siguiente ejemplo, creamos una instancia de Persona
instancia, establecer sus propiedades, asignar persona1
a persona2
, y actualizar el nombre de pila
propiedad de persona1
. Para ver lo que significa pasar por referencia para las clases, generamos el valor de nombre de pila
propiedad de ambos Persona
instancias.
var person1 = Persona (birthPlace: "Belgium") person1.firstName = "Jane" person1.lastName = "Doe" var person2 = person1 person1.firstName = "Janine" print (person1.firstName!) // Janine print (person2. primer nombre!) // Janine
El ejemplo demuestra que las clases son tipos de referencia. Esto significa que persona1
y persona2
referirse o referirse al mismo Persona
ejemplo. Asignando persona1
a persona2
, Swift no crea una copia de persona1
. los persona2
variable puntos al mismo Persona
ejemplo persona1
está apuntando a Cambiando el nombre de pila
propiedad de persona1
también afecta a la nombre de pila
propiedad de persona2
, porque están haciendo referencia a la misma Persona
ejemplo.
Como mencioné varias veces en este artículo, las clases y estructuras son muy similares. Lo que separa clases y estructuras es muy importante. Si los conceptos anteriores no son claros, lo invito a leer el artículo una vez más para dejar que los conceptos que cubrimos se hundan..
En esta entrega de Swift From Scratch, comenzamos a explorar los conceptos básicos de la programación orientada a objetos en Swift. Las clases y estructuras son los componentes fundamentales de la mayoría de los proyectos Swift, y aprenderemos más sobre ellos en las próximas lecciones de esta serie..
En la siguiente lección, continuamos nuestra exploración de clases y estructuras al observar más de cerca las propiedades y la herencia..
Si desea aprender a usar Swift 3 para codificar aplicaciones del mundo real, consulte nuestro curso Crear aplicaciones de iOS con Swift 3. Ya sea que sea nuevo en el desarrollo de aplicaciones de iOS o desee cambiar de Objective-C, este El curso te ayudará a comenzar con Swift para el desarrollo de aplicaciones..