20 de Octubre del 2022 | Jhonatan Montilla
La Programación Orientada a Objetos (OOP en Python) nos permite diseñar programas usando objetos y clases. Este principio une los datos y las funciones relacionadas. C++, C#, Python y Java son algunos de los lenguajes de programación orientada a objetos. En este artículo, vamos a ver los Principios de OOP con ejemplos de código. En Python, una clase es un modelo para crear objetos. Una clase define los atributos y métodos de sus objetos. Una clase define cómo se verá un objeto de esa clase y cómo se comportará.
Un objeto es una instancia de una clase. Representa un elemento específico que se crea en función de la definición de clase. Un objeto tiene su propia identidad, estado y comportamiento únicos. Estamos usando la palabra clave class para crear una clase.
__ init __ es un método especial. También se le conoce como el constructor de la clase, al que se llama automáticamente cuando se crea un objeto de la clase. Se utiliza para inicializar los atributos del objeto y las configuraciones necesarias. El método __ init __ generalmente toma al menos un parámetro, que es self. Se refiere a la instancia del objeto que se está creando.
class Person:
def __init__(self, name, age):
""" Inicializando atributos """
self.name = name
self.age = age
Para crear objetos, necesitamos llamar al constructor, que es el método init. Llamando a ClassName() como un método, que esPerson en este caso. Entonces, al hacer esto, estamos llamando al método init de la clase Person.
# Creating two unique objects
person1 = Person("John", 25)
person2 = Person("Alice", 30)
Los métodos son funciones que se definen dentro de una clase y se llaman en objetos de esa clase. Tienen acceso a los atributos del objeto y pueden modificarlos. El primer parámetro de un método normalmente se llama self. Para llamar a un método, utiliza la notación de puntos, especificando el objeto seguido del nombre del método.
class Person:
def __init__(self, name, age):
""" Inicializando atributos """
self.name = name
self.age = age
def get_info(self):
""" Método """
print("Name:", self.name, " Age:", self.age)
# Creando un objeto único
person1 = Person("John", 25)
# Llamar a un método con anotación
person1.get_info()
Name: John Age: 25
Los métodos de clase se definen utilizando el decorador @classmethod y están vinculados a la clase en lugar de a la instancia de la clase. Tienen acceso a variables de nivel de clase y realizan acciones relacionadas con clases en lugar de objetos individuales. (Para definir una variable de nivel de clase, debe colocarla directamente debajo de la declaración de clase). El primer parámetro de un método de clase normalmente se llama cls, que se refiere a la clase misma. Para llamar a un método de clase en Python, usa el nombre de la clase seguido del nombre del método en notación de puntos. Puedes encontrar más información sobre los decoradores en este artículo.
class Circle:
# class-level variables
pi = 3.14
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return Circle.pi * self.radius * self.radius
@classmethod
def change_pi(cls, new_pi):
cls.pi = new_pi
# Creación de objetos circulares
circle1 = Circle(5)
circle2 = Circle(10)
# Llamar a un método de instancia
area1 = circle1.calculate_area()
print ("area1: ",area1) # Salida: 78.5
# Llamar a un método de clase
Circle.change_pi(3.14159)
area2 = circle2.calculate_area()
print("area2: ",area2) # Salida: 314.159
area1: 78.5 area2: 314.159
Los métodos estáticos se definen utilizando el decorador @staticmethod y no están vinculados a la clase sino a la instancia de la clase. No tienen acceso a los atributos del objeto ni a las variables de nivel de clase, ya que son independientes del estado de la clase. Los métodos estáticos generalmente se usan para funciones de utilidad u operaciones que no dependen del contexto de clase o instancia. Son similares a las funciones regulares. Pero se colocan dentro de una clase con fines organizativos.
class MathUtils:
@staticmethod
def square(x):
return x * x
@staticmethod
def cube(x):
return x * x * x
# Llamar directamente a métodos estáticos
result1 = MathUtils.square(5)
print("5^2: ",result1) # Salida: 25
result2 = MathUtils.cube(3)
print("5^3: ",result2) # Salida: 27
5^2: 25 5^3: 27
Se puede acceder a los métodos estáticos directamente desde la propia clase utilizando la notación de puntos.
El polimorfismo permite que objetos de diferentes tipos sean tratados como objetos de una superclase común. Las subclases tienen acceso a todos los métodos y atributos.
class Person:
def __init__(self, name):
self.name = name
def get_details(self):
return print("Name: ", self.name)
class Employer(Person):
def __init__(self, name, company):
super().__init__(name)
self.company = company
def get_details(self):
return print("Name: ", self.name, ", Company: ", self.company)
# Creando objetos de diferentes clases
person = Person("John")
employer = Employer("Alice", "XYZ Corp")
# Llamar a la función con diferentes objetos
person.get_details() # Salida: Name: John
employer.get_details() # Salida: Name: Alice, Company: XYZ Corp
Name: John Name: Alice , Company: XYZ Corp
En este ejemplo, sublcassPerson es la superclase de Employer sublcass. La clase de empleador tiene acceso a los atributos de la clase de persona y sus métodos. Además, como puede ver, el método get_details() se anula, lo que significa que se redefine en la subclase.
La encapsulación ayuda a proteger los datos del acceso no autorizado y garantiza un mantenimiento adecuado. Algunos modificadores de acceso comunes utilizados en Python:
Público: los miembros públicos (atributos y métodos) son accesibles desde cualquier lugar, tanto dentro como fuera de la clase.
Privado: los miembros privados se indican mediante guiones bajos dobles (__) como prefijo antes del atributo o nombre del método. Solo se puede acceder a ellos dentro de la clase misma, no desde fuera de la clase.
Protegido: los miembros protegidos se indican mediante el uso de un solo guión bajo (_) como prefijo antes del atributo o nombre del método. Se puede acceder a ellos dentro de la clase y sus subclases (clases derivadas), pero no desde fuera de la jerarquía de clases. Los miembros privados y protegidos normales son accesibles desde fuera de la clase. Pero esperamos que los usuarios no interfieran con estos miembros.
class BankAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.__balance = balance # Atributo privado
def get_balance(self):
return self.__balance
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if self.__balance >= amount:
self.__balance -= amount
else:
print("Saldo insuficiente.")
# Crear un objeto CuentaBancaria
account = BankAccount("123456789", 1000)
# Acceso a atributos y métodos de llamada
print("Saldo: ", account.get_balance()) # Salida: 1000
account.deposit(500)
print("Saldo: ", account.get_balance()) # Salida: 1500
account.withdraw(2000) # Salida: Saldo insuficiente
Saldo: 1000 Saldo: 1500 Saldo insuficiente.
Finalmente, la Programación Orientada a Objetos (POO) es un paradigma sólido que permite a los desarrolladores crear y organizar el código de una manera más ordenada y modular. Python, como lenguaje orientado a objetos, ofrece un amplio soporte para los principios de programación orientada a objetos.