Κλάσεις (classes) και αντικείμενα (objects)

Στον αντικειμενοστραφή προγραμματισμό η κλάση αποτελεί τον δομικό λίθο κάθε εφαρμογής. Μα άλλα λόγια κάθε εφαρμογή αποτελείται από έναν αριθμό κλάσεων και κάθε κλάση περιγράφει μια λειτουργική ενότητα.
Η κλάση, αυτό που προσφέρει είναι μια περιγραφή και τις προδιαγραφές με τις οποίες θα δημιουργηθεί ένα ή περισσότερα αντικείμενα και είναι τα αντικείμενα που συμμετέχουν στην εκτέλεση ενός προγράμματος.

Γενικές αρχές για κλάσεις

Κάθε κλάση δηλώνεται με τον πρσδιοριστή: class: Για παράδειγμα: class MyClass: όπου MyClass το όνομα της κλάσης.

Μια κλάση περιέχει έναν συνδυασμό από ιδιότητες ή μεταβλητές (attributes, properties) και συναρτήσεις ή μεθόδους (methods) και έναν δημιουργό ή κατασκευαστή (constructor) ή αρχικοποιητή (initializer).

Οι ιδιότητες και οι μέθοδοι της κλάσης λέγονται μέλη (members) της κλάσης.

Κάθε μέθοδος πρέπει να έχει την προκαθορισμένη παράμετρο self.

Οι ιδιότητες διακρίνονται σε ιδιότητες κλάσης και ιδιότητες αντικειμένου.

Οι ιδιότητες κλάσης δηλώνονται στην κλάση αλλά εκτός των μεθόδων.

Οι ιδιότητες κλάσης λειτουργούν όπως οι μεταβλητές static.

Οι ιδιότητες αντικειμένου δηλώνονται εντός μεθόδων.

Μπορούμε να έχουμε και static μεθόδους.

Παραδείγματα

Κλάση με ιδιότητα κλάσης (static)

class Product:
  price = 125 # δήλωση ιδιότητας κλάσης

print(Product.price) # 125
Product.price  = 180 # αλλαγή τιμής της ιδιότητας κλάσης
print(Product.price) # 180

Η πρόσβαση της ιδιότητας κλάσης γίνεται με το όνομα της κλάσης στην οποία έχει δηλωθεί.

Κλάση με μεταβλητές και μεθόδους.

class Product:
  fpa = 0.2

  def setPrice(self, price):
    self.price = price

  def totalCost(self):
    return self.price * (1 + Product.fpa)

Οι ιδιότητες κλάσης είναι προσβάσιμες με το όνομα της κλάσης και μέσα από την κλάση.

Οι ιδιότητες αντικειμένου έχουν το πρόθεμα self. Έτσι, μπορούμε να τις ξεχωρίζουμε από τις ιδιότητες κλάσης.

Οι ιδιότητες αντικειμένου χρησιμοποιούνται μέσα στις μεθόδους.

Μπορείτε να έχετε απεριόριστες μεταβλητές και συναρτήσεις σε μια κλάση.

Ο κατασκευαστής ή αρχικοποιητής

Μία κλάση μπορεί να περιέχει έναν αρχικοποιητή για τον οποίο ισχύει:

  • Ο αρχικοποιητής είναι μέθοδος και έχει το όνομα __init__()
  • Ο αρχικοποιητής είναι προαιρετικός
  • Ο αρχικοποιητής δεν επιστρέφει ποτέ καμία τιμή
  • Ο αρχικοποιητής εκτελείται αυτόματα κάθε φορά που δημιουργείται ένα νέο αντικείμενο
  • Ο αρχικοποιητής δηλώνεται με τον προσδιοριστή def όπως κάθε μέθοδος.
  • Ο αρχικοποιητής, ως μέθοδος, δέχεται παραμέτρους όπως κάθε μέθοδος.

Παράδειγμα με αρχικοποιητή.

class Product:
  fpa = 0.2

  def __init__(self):
    self.price = 200

  def totalCost(self):
    return self.price * (1 + self.fpa)

Γενικές αρχές για αντικείμενα

Με την βοήθεια της κλάσης μπορούμε να δημιουργήσουμε απεριόριστα αντικείμενα (objects) ή στιγμιότυπα (instances).

Τα αντικείμενα διαφέρουν μεταξύ τους στις τιμές των ιδιοτήτων και ίσως στο αποτέλεσμα που επιστρέφουν οι μέθοδοι.

Παράδειγμα δημιουργίας αντικειμένου χωρίς αρχικοποιητή.

class Product:
  fpa = 0.2

  def setPrice(self, price): # μέθοδος με παράμετρο
    self.price = price

  def totalCost(self): # μέθοδος χωρίς παράμετρο (εξαιρείται το self)
    return self.price * (1 + Product.fpa)

p = Product() # δημιουργία αντικειμένου
p.setPrice(200) # κλήση μεθόδου
print(p.totalCost()) # κλήση μεθόδου και εκτύπωση τιμής επιστροφής

Παράδειγμα δημιουργίας αντικειμένου με αρχικοποιητή.

class Product:
  fpa = 0.2 # ιδιότητα κλάσης

  def __init__(self, price): # αρχικοποιητής
    self.price = price

  def setNewPrice(self, price): # μέθοδος με παράμετρο
    self.price = price

  def totalCost(self): # μέθοδος χωρίς παράμετρο (εξαιρείται το self)
    return self.price * (1 + Product.fpa)

p = Product(300) # δημιουργία αντικειμένου με αρχική τιμή
print(p.totalCost()) # 360
print(p.price) # ανάγνωση (read) τιμής ιδιότητας αντικειμένου
p.price = 500  # γραφή (write) τιμής ιδιότητας αντικειμένου
print(p.price) # 500
print(p.totalCost()) # 600

Δημιουργία αντικειμένου με παράμετρο color.

class Car:

  def __init__(self, color):
    self.color = color # δήλωση ιδιότητας και τιμής

car = Car("red") # δημιουργία αντικειμένου
print(car.color) # red

Δημιουργία αντικειμένου με δύο παραμέτρους.

class Car:

  def __init__(self, color, brand):
    self.color = color # δήλωση ιδιότητας και τιμής
    self.brand = brand

car = Car("red", "fiat") # δημιουργία αντικειμένου
print(car.color, car.brand) # red fiat

Δημιουργία αντικειμένου και αλλαγή τιμής ιδιότητας με μέθοδο.

class Car:

  def __init__(self, color, brand):
    self.color = color # δήλωση ιδιότητας και τιμής
    self.brand = brand # δήλωση ιδιότητας και τιμής

  def set_color(self, color): # μέθοδος για αλλαγή χρώματος
    self.color = color # δήλωση ιδιότητας και τιμής

car = Car("red", "fiat") # δημιουργία αντικειμένου
car.set_color("yellow") # αλλαγή τιμής ιδιότητας
print(car.color, car.brand) # yellow fiat

Μέθοδος static

Η δήλωση μιας μεθόδου ως static γίνεται με δύο τρόπους:

  1. με τη δήλωση staticmethod()
  2. με τη δήλωση @staticmethod

Παράδειγμα με staticmethod().

class Shape:

  def info(msg):
    print(msg)

# δήλωση μεθόδου ως static
Shape.info = staticmethod(Shape.info)

# κλήση μεθόδου static
Shape.info("Αυτή είναι μια μέθοδος static")

Δεν χρειάζεται η self στην μέθοδο.

Παράδειγμα με @staticmethod.

class Shape:

  @staticmethod # δήλωση μεθόδου ως static
  def info(msg):
    print(msg)

# κλήση μεθόδου static
Shape.info("Αυτή είναι μια μέθοδος static")

Ο καταστροφέας (destructor)

Όπως με την __init__() που χρησιμοποιείται για την δημιουργία και την αρχικοποίηση ενός αντικειμένου έτσι και η μέθοδος __del__() χρησιμοποιείται για την καταστροφή ενός αντικειμένου όταν ο κύκλος ζωής του κλείσει.

Η __del__() καλείται αυτόματα κάθε φορά που χρειάζεται μέσα από έναν μηχανισμό που λέγεται garbage collector. Έτσι δεν χρειάζεται να την καλούμε εκτός και αν υπάρχει ειδικός λόγος.

Για να διαγράψετε ένα αντικείμενο χρησιμοποιείτε την εντολή del.

class Example:
  def __init__(self):
    print ("Object created")

  # destructor
  def __del__(self):
    print ("Object destroyed")

myObj = Example() # δημιουργία αντικειμένου
del myObj # καταστροφή αντικειμένου