Programaci贸n orientada a objetos en Python

    Introducci贸n

    La programaci贸n orientada a objetos (OOP) es un paradigma de programaci贸n en el que diferentes componentes de un programa inform谩tico se modelan a partir de objetos del mundo real. Un objeto es cualquier cosa que tenga algunas caracter铆sticas y pueda realizar una funci贸n.

    Considere un escenario en el que tiene que desarrollar un juego de carreras de autos de F贸rmula 1 utilizando el enfoque de programaci贸n orientada a objetos. Lo primero que debe hacer es identificar objetos del mundo real en la carrera de F贸rmula 1 real. 驴Cu谩les son las entidades en una carrera de F贸rmula 1 que tienen algunas caracter铆sticas y pueden realizar cualquier funci贸n? Una de las respuestas obvias a esta pregunta es el autom贸vil. Un autom贸vil puede tener caracter铆sticas como capacidad del motor, marca, modelo, fabricante, etc. De manera similar, un autom贸vil se puede encender, detener, acelerar, etc. Un piloto puede ser un objeto m谩s en una carrera de F贸rmula 1. Un conductor tiene nacionalidad, edad, sexo, etc., y puede realizar funciones como conducir el autom贸vil, mover la direcci贸n o cambiar la transmisi贸n.

    Al igual que en este ejemplo, en la programaci贸n orientada a objetos crearemos objetos para la entidad del mundo real correspondiente.

    Es importante mencionar aqu铆 que la programaci贸n orientada a objetos no es un concepto dependiente del lenguaje. Es un concepto de programaci贸n general y la mayor铆a de los lenguajes modernos, como Java, C #, C ++ y Python, admiten la programaci贸n orientada a objetos. En este art铆culo, veremos una introducci贸n detallada a la programaci贸n orientada a objetos en Python, pero antes de eso, veremos algunas de las ventajas y desventajas de la programaci贸n orientada a objetos.

    Pros y contras de la programaci贸n orientada a objetos

    A continuaci贸n se muestran algunas de las ventajas de la programaci贸n orientada a objetos:

    • La programaci贸n orientada a objetos fomenta la reutilizaci贸n. Un programa inform谩tico se escribe en forma de objetos y clases, que tambi茅n se pueden reutilizar en otros proyectos.
    • El enfoque modular utilizado en la programaci贸n orientada a objetos da como resultado un c贸digo altamente mantenible.
    • En la programaci贸n orientada a objetos, cada clase tiene una tarea espec铆fica. Si ocurre un error en una parte del c贸digo, puede rectificarlo localmente sin tener que afectar otras partes del c贸digo.
    • La encapsulaci贸n de datos (que estudiaremos m谩s adelante en el art铆culo) agrega una capa adicional de seguridad al programa desarrollado utilizando el enfoque orientado a objetos.

    Aunque la programaci贸n orientada a objetos tiene varias ventajas, como se discuti贸, tambi茅n tiene algunas desventajas, algunas de las cuales se enumeran a continuaci贸n:

    • Se necesita un conocimiento de dominio detallado del software que se est谩 desarrollando para crear objetos. No todas las entidades del software son candidatas a implementarse como objetos. Puede ser dif铆cil para los novatos identificar esta delgada l铆nea.
    • A medida que agrega m谩s y m谩s clases al c贸digo, el tama帽o y la complejidad del programa aumentan exponencialmente.

    En la siguiente secci贸n, veremos algunos de los conceptos m谩s importantes de la programaci贸n orientada a objetos.

    Como sugiere el nombre, la programaci贸n orientada a objetos se trata de objetos. Sin embargo, antes de que se pueda crear un objeto, necesitamos definir la clase para el objeto.

    Clase

    Una clase de programaci贸n orientada a objetos sirve como modelo para el objeto. Una clase puede considerarse como un mapa de la casa. Puede hacerse una idea de c贸mo se ve la casa simplemente viendo el mapa. Sin embargo, una clase en s铆 misma no es nada. Por ejemplo, un mapa no es una casa, solo explica c贸mo se ver谩 la casa real.

    La relaci贸n entre una clase y un objeto se puede comprender observando la relaci贸n entre un autom贸vil y un Audi. Un Audi es en realidad un autom贸vil. Sin embargo, no existe solo un autom贸vil. Un autom贸vil es un concepto abstracto, en realidad se implementa en forma de Toyota, Ferrari, Honda, etc.

    La palabra clave classse usa para crear una clase en Python. El nombre de la clase sigue a la classpalabra clave, seguido del car谩cter de dos puntos. El cuerpo de la clase comienza en una nueva l铆nea, con sangr铆a en una pesta帽a desde la izquierda.

    Veamos c贸mo podemos crear una clase muy b谩sica en Python. Eche un vistazo al siguiente c贸digo:

    # Creates class Car
    class Car:
    
        # create class attributes
        name = "c200"
        make = "mercedez"
        model = 2008
    
        # create class methods
        def start(self):
            print ("Engine started")
    
        def stop(self):
            print ("Engine switched off")
    

    En el ejemplo anterior, creamos una clase llamada Carcon tres atributos: name, make, y model. La carclase tambi茅n contiene dos m茅todos: start()y stop().

    Objetos

    Anteriormente, dijimos que una clase proporciona un plano. Sin embargo, para utilizar realmente los objetos y m茅todos de una clase, necesita crear un objeto a partir de esa clase. Hay pocos m茅todos y atributos de clase que se pueden usar sin un objeto, que veremos en la secci贸n posterior. Por ahora, solo tenga en cuenta que, de forma predeterminada, necesitamos crear un objeto de una clase antes de que podamos usar sus m茅todos y atributos.

    Un objeto tambi茅n se denomina instancia; por lo tanto, el proceso de creaci贸n de un objeto de una clase se denomina instanciaci贸n. En Python, para crear un objeto de una clase, simplemente necesitamos escribir el nombre de la clase seguido de par茅ntesis de apertura y cierre.

    Creemos un objeto de la Carclase que creamos en la 煤ltima secci贸n.

    # Creates car_a object of Car class
    car_a = Car()
    
    # Creates car_b object of car class
    car_b = Car()
    

    En el script anterior, creamos dos objetos de la clase car: car_ay car_b. Para comprobar el tipo de objetos que creamos, podemos usar el typem茅todo y pasarle el nombre de nuestro objeto. Ejecute el siguiente script:

    print(type(car_b))
    

    En la salida, ver谩:

    <class '__main__.Car'>
    

    Lo que dice que el tipo de car_bobjeto es una clase Car.

    En este punto hemos creado nuestra clase y los objetos correspondientes. Ahora es el momento de acceder a los atributos de clase y llamar al m茅todo de clase utilizando el objeto de clase. Para hacerlo, simplemente debe escribir el nombre del objeto, seguido del operador de punto y el nombre del atributo o el m茅todo al que desea acceder o llamar, respectivamente. Eche un vistazo al siguiente ejemplo:

    car_b.start()
    

    En el script anterior, llamamos al start()m茅todo a trav茅s del car_bobjeto. La salida ser谩 la siguiente:

    Engine started
    

    Del mismo modo, puede acceder a un atributo utilizando la siguiente sintaxis:

    print(car_b.model)
    

    En la salida, ver谩 el valor del modelatributo, como se muestra a continuaci贸n:

    2008
    

    Atributos

    En la secci贸n anterior, vimos c贸mo podemos crear objetos de una clase y podemos usar esos objetos para acceder a los atributos de una clase.

    En Python, cada objeto tiene algunos atributos y m茅todos predeterminados adem谩s de los atributos definidos por el usuario. Para ver todos los atributos y m茅todos de un objeto, dir()se puede utilizar la funci贸n incorporada . Intentemos ver todos los atributos del car_bobjeto que creamos en la 煤ltima secci贸n. Ejecute el siguiente script:

    dir(car_b)
    

    En la salida, ver谩 los siguientes atributos:

    ['__class__',
     '__delattr__',
     '__dict__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__gt__',
     '__hash__',
     '__init__',
     '__init_subclass__',
     '__le__',
     '__lt__',
     '__module__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     '__weakref__',
     'make',
     'model',
     'name',
     'start',
     'stop']
    

    Esta funci贸n incorporada es 煤til para inspeccionar todos los atributos y funciones de un objeto, especialmente cuando se usa a trav茅s de REPL de Python.

    Atributos de clase frente a instancia

    Los atributos se pueden categorizar ampliamente en dos tipos: atributos de clase y atributos de instancia. Los atributos de clase son compartidos por todos los objetos de una clase, mientras que los atributos de instancia son propiedad exclusiva de la instancia.

    Recuerde, una instancia es solo otro nombre para el objeto. Los atributos de instancia se declaran dentro de cualquier m茅todo, mientras que los atributos de clase se declaran fuera de cualquier m茅todo. El siguiente ejemplo aclara la diferencia:

    class Car:
    
        # create class attributes
        car_count = 0
    
        # create class methods
        def start(self, name, make, model):
            print ("Engine started")
            self.name = name
            self.make = make
            self.model = model
            Car.car_count += 1
    

    En el script anterior, creamos una clase Carcon un atributo de clase car_county tres atributos de instancia name, makey mode. La clase contiene un m茅todo start()que contiene los tres atributos de instancia. Los valores de los atributos de instancia se pasan como argumentos al start()m茅todo. Dentro del startm茅todo, el car_countatributo se incrementa en uno.

    Es importante mencionar que dentro del m茅todo, los atributos de instancia son referidos usando la selfpalabra clave, mientras que los atributos de clase son referidos por el nombre de clase.

    Creemos un objeto de la Carclase y llamemos al start()m茅todo.

    car_a = Car()
    car_a.start("Corrola", "Toyota", 2015)
    print(car_a.name)
    print(car_a.car_count)
    

    En el script anterior imprimimos el atributo de instancia namey el atributo de clase car_count. Ver谩 en la salida que el car_countatributo tendr谩 un valor de 1, como se muestra a continuaci贸n:

    Engine started
    Corrola
    1
    

    Ahora, creemos otro objeto de la carclase y llamemos al start()m茅todo.

    car_b = Car()
    car_b.start("City", "Honda", 2013)
    print(car_b.name)
    print(car_b.car_count)
    

    Ahora, si imprime el valor del car_countatributo, ver谩 2 en la salida. Esto se debe a que el car_countatributo es un atributo de clase y, por lo tanto, se comparte entre las instancias. El car_aobjeto increment贸 su valor a 1, mientras que el car_bobjeto lo increment贸 de nuevo, por lo tanto, el valor final se convirti贸 en 2. La salida se ve as铆:

    Engine started
    City
    2
    

    M茅todos

    Como describimos anteriormente, en la programaci贸n orientada a objetos, los m茅todos se utilizan para implementar las funcionalidades de un objeto. En la secci贸n anterior, creamos start()y stop()m茅todos para la Carclase. Hasta ahora, hemos estado usando los objetos de una clase para llamar a los m茅todos. Sin embargo, existe un tipo de m茅todo que se puede llamar directamente usando el nombre de la clase. Este m茅todo se llama m茅todo est谩tico.

    M茅todos est谩ticos

    Para declarar un m茅todo est谩tico, debe especificar el @staticmethoddescriptor antes del nombre del m茅todo como se muestra a continuaci贸n:

    class Car:
    
        @staticmethod
        def get_class_details():
            print ("This is a car class")
    
    Car.get_class_details()
    

    En el script anterior, creamos una clase Carcon un m茅todo est谩tico get_class_details(). Llamemos a este m茅todo usando el nombre de la clase.

    Car.get_class_details()
    

    Puede ver que no necesitamos crear una instancia de la Carclase para llamar al get_class_details()m茅todo, sino que simplemente usamos el nombre de la clase. Es importante mencionar que los m茅todos est谩ticos solo pueden acceder a los atributos de clase en Python.

    Devolver varios valores de un m茅todo

    Una de las mejores caracter铆sticas del lenguaje Python es la capacidad de los m茅todos de clase para devolver m煤ltiples valores. Eche un vistazo al siguiente ejemplo:

    class Square:
    
        @staticmethod
        def get_squares(a, b):
            return a*a, b*b
    
    print(Square.get_squares(3, 5))
    

    En el script anterior, creamos una clase nombrada Squarecon un m茅todo est谩tico get_squares(). El m茅todo toma dos par谩metros; multiplica cada par谩metro por s铆 mismo y devuelve ambos resultados usando returndeclaraci贸n. En la salida del script anterior, ver谩 los cuadrados de 3 y 5.

    El m茅todo str

    Hasta ahora hemos estado imprimiendo atributos usando el print()m茅todo. Veamos qu茅 pasa si imprimimos el objeto de una clase.

    Para hacerlo, crearemos una Carclase simple con un m茅todo e intentaremos imprimir el objeto de la clase en la consola. Ejecute el siguiente script:

    class Car:
    
        # create class methods
        def start(self):
            print ("Engine started")
    
    car_a = Car()
    print(car_a)
    

    En el script anterior creamos el car_aobjeto de la Carclase e imprimimos su valor en la pantalla. B谩sicamente, aqu铆 estamos tratando el car_aobjeto como una cadena. La salida se ve as铆:

    <__main__.Car object at 0x000001CCCF4335C0>
    

    La salida muestra la ubicaci贸n de la memoria donde se almacena nuestro objeto. Cada objeto de Python tiene un __str__m茅todo por defecto. Cuando usa el objeto como una cadena, __str__se llama al m茅todo, que de forma predeterminada imprime la ubicaci贸n de memoria del objeto. Sin embargo, tambi茅n puede proporcionar su propia definici贸n del __str__m茅todo. Por ejemplo, mire el siguiente ejemplo:

    # Creates class Car
    class Car:
    
        # create class methods
    
        def __str__(self):
            return "Car class Object"
    
        def start(self):
            print ("Engine started")
    
    car_a = Car()
    print(car_a)
    

    En el script anterior, anulamos el __str__m茅todo proporcionando nuestra propia definici贸n personalizada para el m茅todo. Ahora, si imprime el car_aobjeto, ver谩 el mensaje “Objeto de clase de autom贸vil” en la consola. Este es el mensaje que imprimimos dentro de nuestro __str__m茅todo personalizado .

    Con este m茅todo, puede crear descripciones personalizadas y m谩s significativas para cuando se imprime un objeto. Incluso podr铆a mostrar algunos de los datos dentro de la clase, como el namede una Personclase.

    Constructores

    Un constructor es un m茅todo especial que se llama de forma predeterminada cada vez que crea un objeto de una clase.

    Para crear un constructor, debe crear un m茅todo con palabra clave __init__. Eche un vistazo al siguiente ejemplo:

    class Car:
    
        # create class attributes
        car_count = 0
    
        # create class methods
        def __init__(self):
            Car.car_count +=1
            print(Car.car_count)
    

    En el script anterior, creamos una Carclase con un atributo de clase car_count. La clase contiene un constructor que incrementa el valor de car_counte imprime el valor resultante en la pantalla.

    Ahora, siempre Carque se cree un objeto de la clase, se llamar谩 al constructor, el valor de car_countse incrementar谩 y se mostrar谩 en la pantalla. Creemos un objeto simple y veamos qu茅 sucede:

    car_a = Car()
    car_b = Car()
    car_c = Car()
    

    En la salida, ver谩 un valor de 1, 2 y 3 impreso, ya que con cada objeto el valor de la car_countvariable se incrementa y se muestra en la pantalla.

    Excepto por el nombre, el constructor se puede utilizar como m茅todo ordinario. Puede pasar y recibir valores de un constructor. Por lo general, se usa de esta manera cuando desea inicializar valores de atributo al crear una instancia de la clase.

    Local vs Global Variables

    Sabemos que hay dos tipos de atributos de Python, atributos de instancia y atributos de clase. Los atributos de una clase tambi茅n se conocen como variables. Dependiendo del alcance, las variables tambi茅n se pueden clasificar en dos tipos: variables locales y variables globales.

    Variables locales

    Una variable local en una clase es una variable a la que solo se puede acceder dentro del bloque de c贸digo donde est谩 definida. Por ejemplo, si define una variable dentro de un m茅todo, no se puede acceder a ella en ning煤n lugar fuera de ese m茅todo. Mira el siguiente gui贸n:

    # Creates class Car
    class Car:
        def start(self):
            message = "Engine started"
            return message
    

    En el script anterior creamos una variable local messagedentro del start()m茅todo de la Carclase. Ahora creemos un objeto de la Carclase e intentemos acceder a la variable local messagecomo se muestra a continuaci贸n:

    car_a = Car()
    print(car_a.message)
    

    La secuencia de comandos anterior devolver谩 el siguiente error:

    AttributeError: 'Car' object has no attribute 'message'
    

    Esto se debe a que no podemos acceder a la variable local fuera del bloque en el que est谩 definida la variable local.

    Global Variable

    Una variable global se define fuera de cualquier bloque de c贸digo, por ejemplo, m茅todo, sentencias if, etc. Se puede acceder a una variable global en cualquier parte de la clase. Eche un vistazo al siguiente ejemplo.

    # Creates class Car
    class Car:
        message1 = "Engine started"
    
        def start(self):
            message2 = "Car started"
            return message2
    
    car_a = Car()
    print(car_a.message1)
    

    En el script anterior, creamos una variable global message1e imprimimos su valor en la pantalla. En la salida, ver谩 el valor de la message1variable, impreso sin error.

    Es importante mencionar que existe una diferencia entre los atributos de clase e instancia, y las variables locales y globales. Los atributos de clase e instancia difieren en la forma en que se accede a ellos, es decir, utilizando el nombre de la clase y el nombre de la instancia. Por otro lado, las variables locales y globales difieren en su alcance, es decir, en el lugar donde se puede acceder a ellas. Solo se puede acceder a una variable local dentro del m茅todo. Aunque en este art铆culo, tanto la variable local como los atributos de instancia se definen dentro del m茅todo, el atributo local se define con la palabra clave self.

    Modificadores de acceso

    Los modificadores de acceso en Python se utilizan para modificar el alcance predeterminado de las variables. Hay tres tipos de modificadores de acceso en Python: p煤blico, privado y protegido.

    Se puede acceder a las variables con los modificadores de acceso p煤blico en cualquier lugar dentro o fuera de la clase, las variables privadas solo se pueden acceder dentro de la clase, mientras que las variables protegidas se pueden acceder dentro del mismo paquete.

    Para crear una variable privada, debe anteponer doble subrayado con el nombre de la variable. Para crear una variable protegida, debe anteponer un gui贸n bajo con el nombre de la variable. Para las variables p煤blicas, no es necesario que agregue ning煤n prefijo.

    Veamos las variables p煤blicas, privadas y protegidas en acci贸n. Ejecute el siguiente script:

    class Car:
        def __init__(self):
            print ("Engine started")
            self.name = "corolla"
            self.__make = "toyota"
            self._model = 1999
    

    En el gui贸n anterior, creamos una sencilla Carclase con un constructor y tres variables name, makey model. La namevariable es p煤blica, mientras que las variables makey modelse han declarado privadas y protegidas, respectivamente.

    Creemos un objeto de la Carclase e intentemos acceder a la namevariable. Ejecute el siguiente script:

    car_a = Car()
    print(car_a.name)
    

    Dado que namees una variable p煤blica, podemos acceder a ella fuera de la clase. En la salida, ver谩 el valor del nameimpreso en la consola.

    Ahora intentemos imprimir el valor de la makevariable. Ejecute el siguiente script:

    print(car_a.make)
    

    En la salida, ver谩 el siguiente mensaje de error:

    AttributeError: 'Car' object has no attribute 'make'
    

    Hemos cubierto la mayor铆a de los conceptos b谩sicos de programaci贸n orientada a objetos en las 煤ltimas secciones. Ahora, hablemos de los pilares de la programaci贸n orientada a objetos: polimorfismo, herencia y encapsulaci贸n, denominados colectivamente PIE.

    Herencia

    La herencia en la programaci贸n orientada a objetos es bastante similar a la herencia del mundo real, donde un ni帽o hereda algunas de las caracter铆sticas de sus padres, adem谩s de sus propias caracter铆sticas 煤nicas.

    En la programaci贸n orientada a objetos, la herencia significa una relaci贸n IS-A. Por ejemplo, un autom贸vil es un veh铆culo. La herencia es uno de los conceptos m谩s sorprendentes de la programaci贸n orientada a objetos, ya que fomenta la reutilizaci贸n del c贸digo.

    La idea b谩sica de la herencia en la programaci贸n orientada a objetos es que una clase puede heredar las caracter铆sticas de otra clase. La clase que hereda otra clase se llama clase secundaria o clase derivada, y la clase que hereda otra clase se llama clase principal o base.

    Echemos un vistazo a un ejemplo muy simple de herencia. Ejecute el siguiente script:

    # Create Class Vehicle
    class Vehicle:
        def vehicle_method(self):
            print("This is parent Vehicle class method")
    
    # Create Class Car that inherits Vehicle
    class Car(Vehicle):
        def car_method(self):
            print("This is child Car class method")
    

    En el script anterior, creamos dos clases Vehicleclass, y la Carclase que hereda la Vehicleclase. Para heredar una clase, simplemente debe escribir el nombre de la clase principal dentro del par茅ntesis que sigue al nombre de la clase secundaria. La Vehicleclase contiene un m茅todo vehicle_method()y la clase secundaria contiene un m茅todo car_method(). Sin embargo, dado que la Carclase hereda la Vehicleclase, tambi茅n heredar谩 el vehicle_method().

    Veamos esto en acci贸n. Ejecute el siguiente script:

    car_a = Car()
    car_a.vehicle_method() # Calling parent class method
    

    En el script anterior, creamos un objeto de la Carclase y lo llamamos vehicle_method()usando ese Carobjeto de clase. Puede ver que la Carclase no tiene ninguno, vehicle_method()pero dado que ha heredado la Vehicleclase que contiene vehicle_method(), la clase car tambi茅n puede usarlo. La salida se ve as铆:

    This is parent Vehicle class method
    

    En Python, una clase padre puede tener varios hijos y, de forma similar, una clase hijo puede tener varias clases padre. Echemos un vistazo al primer escenario. Ejecute el siguiente script:

    # Create Class Vehicle
    class Vehicle:
        def vehicle_method(self):
            print("This is parent Vehicle class method")
    
    # Create Class Car that inherits Vehicle
    class Car(Vehicle):
        def car_method(self):
            print("This is child Car class method")
    
    # Create Class Cycle that inherits Vehicle
    class Cycle(Vehicle):
        def cycleMethod(self):
            print("This is child Cycle class method")
    

    En el script anterior, la Vehicleclase principal es heredada por dos clases secundarias Cary Cycle. Ambas clases secundarias tendr谩n acceso a la vehicle_method()clase principal. Ejecute el siguiente script para ver eso:

    car_a = Car()
    car_a.vehicle_method() # Calling parent class method
    car_b = Cycle()
    car_b.vehicle_method() # Calling parent class method
    

    En la salida, ver谩 la salida del vehicle_method()m茅todo dos veces como se muestra a continuaci贸n:

    This is parent Vehicle class method
    This is parent Vehicle class method
    

    Puede ver c贸mo una clase principal puede ser heredada por dos clases secundarias. Del mismo modo, un ni帽o puede tener varios padres. Echemos un vistazo al ejemplo:

    class Camera:
        def camera_method(self):
            print("This is parent Camera class method")
    
    class Radio:
        def radio_method(self):
            print("This is parent Radio class method")
    
    class CellPhone(Camera, Radio):
         def cell_phone_method(self):
            print("This is child CellPhone class method")
    

    En el gui贸n anterior, creamos tres clases: Camera, Radio, y CellPhone. La Cameraclase y las Radioclases son heredadas por la CellPhoneclase, lo que significa que la CellPhoneclase tendr谩 acceso a los m茅todos de ambas clases Cameray Radio. La siguiente secuencia de comandos verifica esto:

    cell_phone_a = CellPhone()
    cell_phone_a.camera_method()
    cell_phone_a.radio_method()
    

    La salida se ve as铆:

    This is parent Camera class method
    This is parent Radio class method
    

    Polimorfismo

    El t茅rmino polimorfismo significa literalmente tener m煤ltiples formas. En el contexto de la programaci贸n orientada a objetos, el polimorfismo se refiere a la capacidad de un objeto de comportarse de m煤ltiples formas.

    El polimorfismo en la programaci贸n se implementa mediante la sobrecarga de m茅todos y la anulaci贸n de m茅todos.

    Sobrecarga de m茅todos

    La sobrecarga de m茅todos se refiere a la propiedad de un m茅todo de comportarse de diferentes maneras dependiendo del n煤mero o tipos de par谩metros. Eche un vistazo a un ejemplo muy simple de sobrecarga de m茅todos. Ejecute el siguiente script:

    # Creates class Car
    class Car:
       def start(self, a, b=None):
            if b is not None:
                print (a + b)
            else:
                print (a)
    

    En el script anterior, si start()se llama al m茅todo pasando un solo argumento, el par谩metro se imprimir谩 en la pantalla. Sin embargo, si pasamos 2 argumentos al start()m茅todo, agregar谩 ambos argumentos e imprimir谩 el resultado de la suma.

    Probemos con un solo argumento primero:

    car_a = Car()
    car_a.start(10)
    

    En la salida, ver谩 10. Ahora intentemos pasar 2 argumentos:

    car_a.start(10,20)
    

    En la salida, ver谩 30.

    Anulaci贸n de m茅todo

    La anulaci贸n de m茅todo se refiere a tener un m茅todo con el mismo nombre en la clase secundaria que en la clase principal. La definici贸n del m茅todo difiere en las clases principal y secundaria, pero el nombre sigue siendo el mismo. Tomemos un m茅todo de ejemplo simple anulado en Python.

    # Create Class Vehicle
    class Vehicle:
        def print_details(self):
            print("This is parent Vehicle class method")
    
    # Create Class Car that inherits Vehicle
    class Car(Vehicle):
        def print_details(self):
            print("This is child Car class method")
    
    # Create Class Cycle that inherits Vehicle
    class Cycle(Vehicle):
        def print_details(self):
            print("This is child Cycle class method")
    

    En el script anterior, las clases Cary Cycleheredan la Vehicleclase. La clase de veh铆culo tiene un print_details()m茅todo, que es anulado por las clases secundarias. Ahora, si llama al print_details()m茅todo, la salida depender谩 del objeto a trav茅s del cual se llama al m茅todo. Ejecute el siguiente script para ver este concepto en acci贸n:

    car_a = Vehicle()
    car_a. print_details()
    
    car_b = Car()
    car_b.print_details()
    
    car_c = Cycle()
    car_c.print_details()
    

    La salida se ver谩 as铆:

    This is parent Vehicle class method
    This is child Car class method
    This is child Cycle class method
    

    Puede ver que la salida es diferente, aunque el print_details()m茅todo se llama a trav茅s de clases derivadas de la misma clase base. Sin embargo, dado que las clases secundarias han anulado el m茅todo de la clase principal, los m茅todos se comportan de manera diferente.

    Encapsulamiento

    La encapsulaci贸n es el tercer pilar de la programaci贸n orientada a objetos. La encapsulaci贸n simplemente se refiere a la ocultaci贸n de datos. Como principio general, en la programaci贸n orientada a objetos, una clase no deber铆a tener acceso directo a los datos de la otra clase. M谩s bien, el acceso debe controlarse mediante m茅todos de clase.

    Para proporcionar acceso controlado a los datos de la clase en Python, se utilizan los modificadores de acceso y las propiedades. Ya hemos visto modificadores de acceso, en esta secci贸n, veremos propiedades en acci贸n.

    Supongamos que queremos asegurarnos de que el modelo de autom贸vil siempre debe estar entre 2000 y 2018. Si un usuario intenta ingresar un valor menor que 2000 para el modelo de autom贸vil, el valor se establece autom谩ticamente en 2000 y si el valor ingresado es mayor que 2018, debe establecerse en 2018. Si el valor est谩 entre 2000 y 2018, no debe cambiarse. Podemos crear una propiedad para el atributo del modelo que implemente esta l贸gica de la siguiente manera:

    # Creates class Car
    class Car:
    
        # Creates Car class constructor
        def __init__(self, model):
            # initialize instance variables
            self.model = model
    
        # Creates model property
        @property
        def model(self):
            return self.__model
    
        # Create property setter
        @model.setter
        def model(self, model):
            if model < 2000:
                self.__model = 2000
            elif model > 2018:
                self.__model = 2018
            else:
                self.__model = model
    
        def getCarModel(self):
            return "The car model is " + str(self.model)
        
    carA = Car(2088)
    print(carA.getCarModel())
    

    Una propiedad tiene tres partes. Tienes que definir el atributo, que est谩 modelen el script anterior. A continuaci贸n, debe definir la propiedad para el atributo usando el decorador @property. Finalmente, debe crear un establecedor de propiedades que sea un @model.setterdescriptor en el script anterior.

    Ahora, si intenta ingresar un valor mayor que 2018 para el atributo del modelo, ver谩 que el valor est谩 establecido en 2018. Probemos esto. Ejecute el siguiente script:

    car_a = Car(2088)
    print(car_a.get_car_model())
    

    Aqu铆 estamos pasando 2088 como el valor de model, sin embargo, si imprime el valor del modelatributo a trav茅s de la get_car_model()funci贸n, ver谩 2018 en la salida.

    Conclusi贸n

    En este art铆culo, estudiamos algunos de los conceptos de programaci贸n orientada a objetos m谩s importantes. La programaci贸n orientada a objetos es uno de los paradigmas de programaci贸n m谩s famosos y utilizados. La importancia de la programaci贸n orientada a objetos se refleja en el hecho de que la mayor铆a de los lenguajes de programaci贸n modernos est谩n totalmente orientados a objetos o admiten programaci贸n orientada a objetos.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *