Saturday, July 2, 2022

Python - Classes and Inheritance

class MyClass:
  x = 5
 
p1 = MyClass()
# 5
print(p1.x)

print("---")

# built-in __init__() function is called on object instatiation
class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

p1 = Person("John", 36)

# John, 36
print(p1.name)
print(p1.age)

print("===")


class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)
# Hello my name is John
p1.myfunc()

#36
print(p1.age)

# Set property
p1.age = 40

# 40
print(p1.age)

# <class '__main__.Person'>
# So this tells us it is an object of type Person

print (type(p1))


# Delete an object
del p1

# A class with no definition
class Person:
    pass

print("******")

# Inheritance, Parents, Children

# First define a class

class Person:
  def __init__(self, fname, lname):
    self.firstname = fname
    self.lastname = lname

  def printname(self):
    print(self.firstname, self.lastname)

x = Person("John", "Doe")

# John Doe
x.printname()

# Now create a child of the parent

class Student(Person):
    pass

y = Student("Sarah", "Smith")
# Sarah Smith
y.printname()

print("------------")

# Notice that we never defined a method called printname() in the child class
# But the Student inherited the methods of the parent class (Person)

class Student(Person):
    def __init__(self, fname, lname):
        #add properties here
        pass
    
y = Student("Sarah", "Smith")

# This next line breaks because we over-rode the inheritance of the parent
# by defining our own __init__() function in the chil
# In other words, the child's __init__() function overrides the inheritance
# of the parent's __init()__ function
#y.printname()

# We fix it by adding a call to the parent's __init__() function

class Student(Person):
    def __init__(self, fname, lname):
        Person.__init__(self, fname, lname)


y = Student("Sarah", "Smith")

# Now this works
# Sarah Smith
y.printname()

print("------------")

# By using super() we automatically inherit the methods and properties from parent
class Student(Person):
  def __init__(self, fname, lname):
    super().__init__(fname, lname)
    self.graduationyear = 2019

    
y = Student("Sarah", "Smith")
# Sarah Smith
y.printname()
# 2019
print (y.graduationyear)

print("============")

# Make graduationyear a variable

class Student(Person):
  def __init__(self, fname, lname, year):
    super().__init__(fname, lname)
    self.graduationyear = year

y = Student("Sarah", "Smith", 2022)

# Sarah Smith
y.printname()
# 2022
print (y.graduationyear)

print("<><><><><><>")

# Add a method

class Student(Person):
  def __init__(self, fname, lname, year):
    super().__init__(fname, lname)
    self.graduationyear = year

  def welcome(self):
    print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)