1. 程式人生 > 其它 >面向物件的特徵

面向物件的特徵

面向物件的特徵之一:繼承

什麼是繼承?

繼承是一種建立新類的方式,新建的類可以繼承一個或多個父類(python支援多繼承),父類又可稱為基類或超類,新建的類稱為派生類或子類。

子類會繼承父類的屬性,也可使用父類的方法,從而解決程式碼冗餘問題

python中類的繼承分為單繼承和多繼承

# 單繼承
# 以學生選課系統為例
# 父類,公共類
class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

# 學生類
class Student(People):

    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        People.__init__(self, name, age, gender)
        self.courses = course

    def choose_course(self, course):
        self.courses.append(course)
        print('%s 選課成功 %s' % (self.name, self.courses))


stu = Student('tony', 19, 'male')

# teacher類
class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        People.__init__(self, name, age, gender)

    def score(self, stu_obj, score):
        stu_obj.score = score  # 給學生打分
        print('%s給%s打了%s分' % (self.name, stu_obj.name, score))


tea = Teacher('lucy', 28, 'male', 10)
print(tea.name)
print(tea.level)

單繼承下屬性查詢

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        #
        print('Foo.f2')
        self.f1()


class Bar(Foo):
    def f1(self):
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()


# 練習
class Foo:
    def __f1(self):  # _Foo__f1()
        print('Foo.f1')

    def f2(self):
        #
        print('Foo.f2')
        self.__f1()  # _Foo__f1()


class Bar(Foo):
    def __f1(self):  # # _Bar__f1()
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()

多繼承下屬性查詢

# 新式類:按照廣度優先查詢
# 經典類:按照深度優先查詢
# python3中都是新式類
class A(object):
    def test(self):
        print('from A')


class B(A):
    # def test(self):
    #     print('from B')
    pass

class C(A):
    # def test(self):
    #     print('from C')
    pass


class D(B):
    # def test(self):
    #     print('from D')
    pass

class E(C):
    # def test(self):
    #     print('from E')
    pass


class F(D, E):
    # def test(self):
    #     print('from F')
    pass


f1 = F()
f1.test()


super()和mro列表

 class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        
class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        super().__init__(name, age, gender) # super的使用

        
# mro列表練習1
class A:
    def test(self):
        print('from A.test')
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass


c = C()
c.test()


# mro列表練習2 
class B:
    def test(self):
        print('B---->test')

    def aaa(self):
        print('B---->aaa')

class A:
    def test(self):
        print('A---->test')
        super().aaa()


class C(A, B):
    def aaa(self):
        print('C----->aaa')


c = A()
# c.test()  # 列印結果:
print(A.mro())

抽象類

抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被例項化

為什麼要有抽象類

​ 如果說類是從一堆物件中抽取相同的內容而來的,那麼抽象類就是從一堆類中抽取相同的內容而來的,內容包括資料屬性和函式屬性

#一切皆檔案
import abc #利用abc模組實現抽象類

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定義抽象方法,無需實現功能
    def read(self):
        '子類必須定義讀功能'
        pass

    @abc.abstractmethod #定義抽象方法,無需實現功能
    def write(self):
        '子類必須定義寫功能'
        pass

# class Txt(All_file):
#     pass
#
# t1=Txt() #報錯,子類沒有定義抽象方法

class Txt(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print('文字資料的讀取方法')

    def write(self):
        print('文字資料的讀取方法')

class Sata(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print('硬碟資料的讀取方法')

    def write(self):
        print('硬碟資料的讀取方法')

class Process(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print('程序資料的讀取方法')

    def write(self):
        print('程序資料的讀取方法')

txt1=Txt()

sata1=Sata()

process1=Process()

#這樣大家都是被歸一化了,也就是一切皆檔案的思想
txt1.read()
sata1.write()
process1.read()

print(txt1.all_type)
print(sata1.all_type)
print(process1.all_type)

面向物件的三大特徵之二:多型

多型指的是一類事物有多種形態

比如動物有多種形態:人,狗,豬

import abc
class Animal(metaclass=abc.ABCMeta): #同一類事物:動物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #動物的形態之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #動物的形態之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #動物的形態之三:豬
    def talk(self):
        print('say aoao')

多型性

多型性是指在不考慮例項型別的情況下使用例項

在面向物件方法中一般是這樣表述多型性:
向不同的物件傳送同一條訊息(!!!obj.func():是呼叫了obj的方法func,又稱為向obj傳送了一條訊息func),不同的物件在接收時會產生不同的行為(即方法)。
也就是說,每個物件可以用自己的方式去響應共同的訊息。所謂訊息,就是呼叫函式,不同的行為就是指不同的實現,即執行不同的函式。

比如:老師.下課鈴響了(),學生.下課鈴響了(),老師執行的是下班操作,學生執行的是放學操作,雖然二者訊息一樣,但是執行的效果不同

peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是動物,只要是動物肯定有talk方法
#於是我們可以不用考慮它們三者的具體是什麼型別,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更進一步,我們可以定義一個統一的介面來使用
def func(obj):
    obj.talk()