1. 程式人生 > 其它 >面向物件-靜態於動態方法,繼承

面向物件-靜態於動態方法,繼承

目錄

動態方法於靜態方法

# 動態方法
1.繫結給物件的方法
class Student:
    def run(self):
        print(self)
# 類呼叫繫結給物件的方法,有幾個引數就需要傳及格引數
Student.run(123)
#物件呼叫繫結給物件的方法會自動將物件當作第一個引數傳入
obj1.run()


2.繫結給類的方法,會自動將類當作第一個引數傳入
class Student:
      @classmethod
      def eat(cls):
        prtin(cls)
# 類呼叫繫結給類的方法,會自動將類作為第一個引數傳入
print(Student)  # <class '__main__.Student'>
    Student.eat()  # <class '__main__.Student'>
# 物件呼叫繫結給類的方法也不要傳參,會將產生該物件的類自動當作第一個引數傳入
    obj1.eat()  # <class '__main__.Student'>

    
# 靜態方法
class Student:
    @staticmethod
    def speak(a):
        print(a)
1.普普通通的函式,無論誰呼叫,都必須傳固定的引數個數
# 類呼叫靜態方法要自己傳值
Student.speak(111)
#物件呼叫靜態方法也要自己傳值
object.speak(111)

面向物件三大特徵之一:繼承

'''
面向物件三大特徵:繼承、封裝、多型
其中最重要的就是繼承
'''
# 繼承的含義
	現實生活中繼承是用來描述人與人之間資源的從屬關係
    eg:兒子繼承父親的產業
        面向物件中繼承則是用來描述類魚類之間資料的從屬關係
        eg:類A繼承了類B 那麼類A就可以使用類B中的資料和功能
            
# 繼承的目的
現實生活中通過繼承,可以快速積累資源,少奮鬥很多年,並且可以多繼承
面向物件中可以通過繼承減少程式碼冗餘 提升開發效率 同樣也支援多繼承
# 繼承的基本使用
class a(b):
	pass
我們將被繼承的類稱為父類:b
繼承別人的類稱為子類:a
class a(b,v,d):
    pass
在python中可以同時繼承多個父類

繼承的本質

抽象:由下往上抽取相同的特徵
繼承:由上往下繼承資料功能
'''
在面向物件程式設計過程中 其實類和父類的主要功能都是減少程式碼冗餘
物件:資料於功能的結合體
類:多個物件相同資料功能的結合體
父類:多個類相同資料和功能的結合體
'''
class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
class Teacher(Person):
    def teach(self):
        print(f'{self.name}老師正在講課')
class Student(Person):
    def study(self):
        print(f'{self.name}學生正在學習')
stu1 = Student('tom', 18, 'male')

名字的查詢順序

# 不繼承的情況下
名字的查詢順序
	先從物件自己的名稱空間中查詢 沒有則去類裡面的名稱空間查詢
    1.物件 ==> 2.類
    '''注意:設定值的情況下實在滋生的名稱空間中新增或者修改資料'''
# 單繼承的情況下
名字查詢順序
先從物件自己的名稱空間中查詢 沒走就去產生物件的類中查詢,在沒有,就去父類裡面查詢
1.物件 ==》 2.生成物件的類 ==》 3.父類

經典案例
  	class A:
      def f1(self):
          print('from A.f1')
      def f2(self):
          print('from A.f2')
          self.f1()  '''以後看到self點東西 一定要問自己self是誰'''
    class MyClass(A):
       def f1(self):
            print('from MyClass.f1')
    obj = MyClass()
    obj.f2()
    # 執行的方法分別是A裡面的f2和MyClass裡面的f1,,,牢記查詢順序。
    
# 多繼承
'''
在python2中存在經典類和新式類
python3中只有新式類
	新式類:直接或者簡介繼承了object或者其子類的類
	經典類:不繼承任何類
區分的關鍵在於是否繼承了一個預設的object類
'''
    class A:
      pass
    # print A.__bases__  # 空的(在python2中)
    # print(A.__bases__)  # (<class 'object'>,)在python3中
    """
    有時候我們在定義類的時候會習慣性的寫
    class MyClass(object):
        pass
    為了相容python2和python3
    """
強調:研究菱形和非菱形問題object不參與影象構建
非菱形繼承的情況下
	父類名字查詢順序按照從左到右一次查詢,如果多個父類還有分類‘深度優先’(也就是查詢先父類的父類,在查詢別的父類)
菱形繼承的情況下
	父類中名字的查詢順序就是按照繼承是從左到右依次查詢,如果多個父類還有分類 那麼遵循‘廣度優先’(從左到右,一次查詢,父類,最後在查詢父類的父類)
### 名字查詢順序永遠是從當前物件自身開始查詢

派生類

'''當一個類,想要在父類的基礎上新增新的屬性的時候,可以使用super方法來達成目的,,而這個類就是父類的派生類(相當於子類,只是在父類的基礎上新增額外的東西)'''
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age


class Student(Person):
    def __init__(self, name, age, gender):
        # super(Person, self).__init__(name, age)  # 子類呼叫父類的語法,完整版
        super().__init__(name, age)  # 子類呼叫父類的語法,精簡版
        self.gender = gender


'''
如果自己寫的子類需要使用父類的方法 並且還需要基於該方法做擴充套件
這樣的子類我們稱之為派生類(本質還是子類)      
   那麼可以使用super關鍵字來實現
'''
s1 = Student('kevin', 28, 'female')
print(s1.__dict__)  # {'name': 'kevin', 'age': 28, 'gender': 'female'}

派生功能前瞻

class MyClass(list):
    def append(self,args):
        if args == 123:
            print('數字123不能追加')
            return
        super(MyClass, self).append(args)
obj1 = MyClass()
obj1.append(333)
obj1.append(222)
obj1.append(123)
print(obj1)