1. 程式人生 > 其它 >面向物件的三大特徵(封裝、繼承、多型)

面向物件的三大特徵(封裝、繼承、多型)

面向物件的三大特徵(封裝、繼承、多型)

  • 繼承
  • 繼承的屬性查詢順序
  • super()和mro()列表
  • 多型與多型性

一、繼承(重要)

  1. 繼承的概念

    繼承就是新建類的一種方式,新建的類我們稱為子類或者叫派生類,被繼承的類我們稱為父類或者基類

    子類可以使用父類中的屬性或者方法

  2. 繼承的作用

    類解決了物件與物件之間的程式碼冗餘問題

    繼承解決的是類與類之間的程式碼冗餘問題

  3. 繼承的使用

    新式類:繼承了object類的子子孫孫類都是新式類

    經典類:沒有繼承object類的子子孫孫類都是經典類

    新式類和經典類只有在python2中區分

二、類的繼承

# 以學生選課系統為例
# 父類,公共類
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('ly', 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('ly', 19, 'male', 10) print(tea.name) print(tea.level)

三、繼承的屬性查詢順序

  1.單繼承下屬性查詢

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()

  2. 多繼承下屬性查詢

# 新式類:按照廣度優先查詢
# 經典類:按照深度優先查詢
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())

五、多型與多型性

  多型就是多種狀態

# 抽象類: 抽象類只能被繼承,不能被例項化
class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod  # 該方法已經是抽象方法了
    def speak(self): pass

    @abc.abstractmethod
    def login(self):pass

class People(Animal):
    def speak(self):
        # print('嗷嗷嗷')
        pass
    def login(self):
        pass


class Pig(Animal):
    def speak(self):
        print('哼哼哼')


class Dog(Animal):
    def speak(self):
        print('汪汪汪')


obj = People()
obj.speak()


# 多型練習
class Pig():
    def speak(self):
        print('哼哼哼')


class Dog():
    def speak(self):
        print('汪汪汪')

class Txt():
    def speak(self):
        print('Txt')

obj = People()
obj1 = Pig()
obj2 = Dog()
obj3 = Txt()

# 多型帶來的特性:在不用考慮物件資料型別的情況下,直接呼叫對應的函式

def animal(animal):
    return animal.speak()

animal(obj)
animal(obj1)
animal(obj2)
animal(obj3)

# 父類限制子類的行為
class Animal():
    def speak(self):
        raise Exception("必須實現speak方法")