#inheritance

class Class1():

def __init__(self):
print("class 1 created")

def method_1(self):
print("method 1")

def method_2(self):
print("method 2")

my_instance = Class1()

my_instance.method_1()
my_instance.method_2()

class Class2(Class1): # parantez içine (Class1) yazarak "Class2" içine "Class1"i inherite ettik yani miras aldık

def __init__(self):
Class1.__init__(self) # istersek miras aldığımız Class1'in __init__ fonksiyonunu bile bu şekilde çağırabiliriz
print("class 2 created")

def method_3(self):
print("method 3")

# override --> bu şekilde miras aldığımız bi metodu alıp istediğimiz şekilde değiştirebiliriz. bu işleme override yani üstüne yazmak denir
def method_1(self):
print("method 1 ovveride")

my_instance2 = Class2()

my_instance2.method_1()
my_instance2.method_2()

# my_instance.method_3() gördüğümüz gibi miras Class1 in özelliklerini miras alan (inherite) Class2 içinde tanımladığımız method_3'e parent class (Class1) ile erişemiyoruz
# o yüzden Class1'e ait olan instance (my_instance) ile Class2'ye ait olan method_3() ü çağırmaya kalkarsak hata verir. Yani kısacası babadan oğula erişim yok ama babadan miras olan çocuğu babaya erişimi var. Yani miras babadan oğula olur. Diğer bir değişle;
oğul babaya miras veremez ki gerçek hayatta da böyledir bu durum.

my_instance2.method_1()

my_instance.method_1()