1. 程式人生 > >Python基礎筆記_Day11_Python單繼承、多繼承、重寫方法、Python多型、Python靜態方法和類方法

Python基礎筆記_Day11_Python單繼承、多繼承、重寫方法、Python多型、Python靜態方法和類方法

Day11_Python單繼承、多繼承、重寫方法、Python多型、Python靜態方法和類方法

11.01_Python語言基礎(繼承的介紹)(掌握)
11.02_Python語言基礎(單繼承)(掌握)
11.03_Python語言基礎(多繼承)(掌握)
11.04_Python語言基礎(重寫父類的方法和呼叫父類的方法)(掌握)
11.05_Python語言基礎(多型)(掌握)
11.06_Python語言基礎(類屬性和例項屬性)(掌握)
11.07_Python語言基礎(靜態方法和類方法)(掌握)

11.01_Python語言基礎(繼承的介紹)(掌握)

  • 繼承的概念:
    • 在現實生活中,一般指子女繼承父輩的財產
  • 程式中的繼承:
    • 繼承描述的是事物之間的所屬關係,之前的貓,狗----》動物
    • 程式中可以描述貓和狗繼承動物
      object

           		動物
    	 貓               狗
	加菲    波斯       金毛   二哈

11.02_Python語言基礎(單繼承)(掌握)

  • 生活中的單繼承:
    • 孩子只能有一個親生父親或者母親
  • 程式中的單繼承:
    • 子類只能有一個父類–》子類只能繼承一個父類
      ####單繼承案例:

# 定義一個父類
class Cat(object):
    def __init__(self, name, color):
        self.__name = name
        self.color = color

    def run(self):
        print("%s----在跑" % self.__name)


# 定義一個子類
class Bosi(Cat):
    def setNewName(self, newName):
        self.__name = newName

    def eat(self):
        # print("%s---在吃飯"%self.__name)
        pass


bs = Bosi("波斯", "白色")
# print(bs.__name)
print(bs.color)
bs.eat()

bs.setNewName("加菲")
bs.eat()
bs.run()

說明:
雖然在子類中沒有定義__init__()方法
但是父類有,在子類繼承父類的時候這個方法也就被繼承過來
建立Bosi物件,預設執行那個繼承過來的__init__方法


總結:
子類在繼承的時候,在定義類的時候,小括號中為父類的名字
父類的公有屬性和公有方法會被子類繼承


再贈送一個案例

print("父類中出現私有的情況")

# 定義一個父類
class Animal(object):
    def __init__(self, name="動物", color="白色"):
        self.__name = name
        self.color = color

    def __test(self):
        print(self.__name)
        print(self.color)

    def test(self):
        print(self.__name)
        print(self.color)


# 定義一個子類
class Dog(Animal):

    def Test1(self):
        # print(self.__name)#不能訪問父類的私有屬性
        print(self.color)

    def dogTest2(self):
        # self.__test()#不能訪問父類的私有方法
        self.test()


a = Animal()

# print(a.__name)#報錯,不能通過物件訪問私有屬性
# a.__test()#報錯,不能訪問私有方法
a.test()
print("--------")

d = Dog(name="小花狗", color="黃色")
print(d.color)
d.Test1()
d.dogTest2()

總結:

私有的屬性,不能通過物件直接訪問,可以通過方法進行訪問

私有方法,不能通過物件直接訪問

私有屬性,方法都不會被子類繼承,也不能被訪問

子類繼承的是父類公有是屬性和方法


11.03_Python語言基礎(多繼承)(掌握)

  • 生活中的例子:
    • 騾子是馬和驢的雜交品種
  • 程式中的多繼承:
    • 一個子類有多個父類,並且據有他們的特徵,這被稱為多繼承

# 定義一個父類
class A:
    def printA(self):
        print("----A-----")


# 定義一個父類
class B:
    def printB(self):
        print("----B-----")


# 多繼承
class C(A, B):
    def printC(self):
        print("----C-----")


# 建立C的物件
c = C()
c.printA()
c.printB()
c.printC()

說明:

python中可以多繼承

父類中的方法和屬性,子類會繼承


多個父類中出現相同的方法案例:

print("多個父類中出現相同的方法")


# 如果父類A和B,有一個同名的方法,
# 那麼子類在呼叫方法的時候,執行哪個父類中的方法
# 定義一個父類
class A:
    def printA(self):
        print("----A-----")


# 定義一個父類
class B:
    def printA(self):
        print("----B-----")


# 多繼承
class C(A, B):
    pass


c = C()
c.printA()

print(c)


# 案例:

class base(object):
    def test(self):
        print("base--test")


class D(base):
    def test(self):
        print("D----test")


class E(base):
    def test(self):
        print("E----test")


class F(D, E):
    pass


f = F()
f.test()
print(F.__mro__)  # 可以檢視類的物件搜尋方法時的先後順序

練習:

有一個學校,人數為0,入職的老師和學生,人數增加1,
老師要顯示姓名和工號,學生要顯示姓名和成績

使用繼承

父類 學校

子類 老師 學生


參考程式碼:

print("練習題")


# 學校類
class School:
    # 定義預設的人數為0
    schoolNum = 0

    # 初始化資料
    def __init__(self, name):
        self.name = name
        School.schoolNum += 1
        print("學校新加入的成員:%s" % self.name)
        print("學校現有的學生的人數%s" % School.schoolNum)

    # 自我介紹,姓名和工號,成績
    def sayHello(self):
        print("我叫%s" % self.name)


# 建立老師類
class Teacher(School):
    def __init__(self, name, id):
        a = School(name)
        self.name = name
        self.id = id

    def sayHello(self):
        print("我叫%s,工號為%d" % (self.name, self.id))


# 學生類
class Student(School):
    def __init__(self, name, result):
        self.name = name
        self.result = result
        b = School(name)

    def sayHello(self):
        print("我叫%s,成績:%d" % (self.name, self.result))


# 建立老師物件
t = Teacher("小明", 1000)
t.sayHello()
s = Student("張三", 99)
s.sayHello()

11.04_Python語言基礎(重寫父類的方法和呼叫父類的方法)(掌握)

  • 重寫:
    • 就是子類中,有一個和父類相同名字的方法,在子類中的方法會覆蓋父類中的方法

重寫父類方法

#定義一個父類
class Cat(object):
    def sayHello(self):
        print("hello----1")
#定義子類
class Bosi(Cat):
    def sayHello(self):
        print("hello -------2")
#建立子類的物件
bs = Bosi()
bs.sayHello()

想一想:要求打印出hello ------1,該如何實現

呼叫父類屬性

class Cat(object):
    def __init__(self, name):
        self.name = name
        self.color = "yello"

class Bosi(Cat):
    def __init__(self, name):
        self.name = name
        # 方式1呼叫父類__init__方法,python2中/python3中
        # Cat.__init__(self,name)
        # 方式2:super(),可以完成對父類__init__()的呼叫
        # super(Bosi,self).__init__(name)
        # 方式3:super()直接呼叫__init__()函式
        super().__init__(name)


# super()#一層一層向上
bosi = Bosi("xiaoming")
print(bosi.name)
print(bosi.color)

11.05_Python語言基礎(多型)(掌握)

  • 多型:
    • 定義的型別和執行時的型別不一樣----》多型
  • Python並不支援真正的多型
  • Python中使用虛擬碼來實現多型

Python多型案例:

class F1(object):
    def show(self):
        print("F1.show")

class S1(F1):
    def show(self):
        print("S1.show")
class S2(F1):
    def show(self):
        # super().show()
        print("s2.show")
        # F1.show(self)
        # super(S2,self).show()

# python  動態的言語

def func(F1):
    print("func接受一個數據型別")
    # print(F1.show())
# func(F1)

# s1 = S1()
# s1.show()
s2 = S2()
s2.show()

11.06_Python語言基礎(類屬性和例項屬性)(掌握)

概述:
類屬性就是類物件所擁有的屬性,它被所有類物件的例項物件所公有
類屬性在記憶體中只存一個副本對於公有類屬性和例項屬性在類的外面可以直接被訪問

類屬性

  • 類屬性:
    • 在類中定義的屬性(公有和私有)
      ###類屬性案例:

# 定義一個類:
class People(object):
    name = "xiaoming"  # 公有的屬性
    __age = 12  # 私有屬性


# 建立People類的物件
p = People()
print(p.name)  		# ok
print(People.name)  # ok
# print(p.__age)    # no ok   不能在類外面通過例項物件訪問類的私有屬性
print(People.__age)	# no ok   不能通過類物件訪問私有屬性

例項屬性

# 定義類
class People(object):
    address = "北京"

    def __init__(self):
        self.name = "xiaoming"  # 例項屬性
        self.age = 12  			# 例項屬性


p = People()
p.age = 20
print(p.age)
print(p.name)
print(p.address)

print(People.address)
# print(People.name)  #類物件訪問例項屬性
# print(People.age)   #類物件訪問例項屬性

通過例項物件去修改類屬性

print("@" * 20)

class People(object):
    country = "china"

    def __init__(self):
        self.name = "hhaa"

print(People.country)
p = People()
print(p.country)
p.country = "chinese"  # 例項屬性會遮蔽同名的類屬性
print(p.country)
print(People.country)

del p.country
print(p.country)

總結

如果需要在類外修改類屬性,必須通過類物件去引用再進行修改
如果通過例項物件去引用,會產生一個同名的例項屬性,
這個方式其實是修改例項屬性,不會影響類屬性,
並且之後如果需要通過例項物件去引用該同名的屬性,
例項屬性會強制遮蔽類屬性,即引用的是類屬性,除非刪除該例項屬性

11.07_Python語言基礎(靜態方法和類方法)(掌握)

類方法

類方法:

類物件所擁有的方法,需要使用到修飾器 @classmethod---->類方法

對於類方法,第一個引數必須是類物件,一般以cls表示作為第一個引數

(當然可以用其他的名字,但是不建議修改)

class People(object):
    country = "china"

    @classmethod
    def getCountry(cls):
        return cls.country


p = People()
print(p.country)
print(p.getCountry())		#通過例項物件進行訪問
print(People.country)
print(People.getCountry())  # 通過類物件去引用


print("#" * 20)


p = People()
print(p.country)
print(p.getCountry())  		# 通過例項物件進行訪問
print(People.country)
print(People.getCountry())  # 通過類物件去引用


class People(object):
    country = "china"

    # 類方法
    @classmethod
    def getCountry(cls):
        return cls.country

    @classmethod
    def setCountry(cls, country):
        cls.country = country


p = People()
print(p.getCountry())  		# 可以用例項物件引用
print(People.getCountry())	# 通過類物件的的引用

p.setCountry("chinese")
print(p.getCountry())
print(People.getCountry())

作用:

  • 類方法可以對類屬性進行修改

  • 發現規律:

    • 結果顯示在用類方法對類屬性進行操作修改之後,通過類物件和例項物件訪問都發生了變化

靜態方法

  • 定義:
    • 需要通過修飾器@staticmethod來進行修飾,不需要傳引數

print("#" * 20)


class People(object):
    country = "china"

    # def getCountry(self):
    #     return " "
    @staticmethod
    def getCountry():
        return People.country


print(People.getCountry())
p = People()
print(p.getCountry())

總結

從類方法和例項方法(普通方法)和靜態方法
類方法第一個引數是類物件cls,那麼通過cls的引用必定是類物件的屬性和方法
例項方法第一個引數self,自身,那麼通過self引用的可能是類屬性,也可以是例項屬性(具體分析)

問題?
如果出現相同名稱的類屬性和例項屬性
例項屬性優先順序更高
靜態方法:靜態方法中不需要傳遞任何引數(額外的定義引數),
在靜態方法中的引用是類屬性,必須通過類物件來引用