Python基础之十一(类的方法和特性)

一、类的方法

1、实例方法(方法也称函数)【常用】

定义:需要对类进行实例化之后才能调用的方法,默认传参实例本身,没有修饰符

语法:

  def 方法名(self):

    方法体

调用:

  在类外部:实例.方法名()

  在类内部:self.方法名()

例子:

class Dog:
    # 实例方法
    def eat(self):
        print('狗狗吃饭')

    # 实例方法
    def sleep(self):
        self.eat()  # 在类内部调用eat实例方法
        print('狗狗睡觉')


if __name__ == '__main__':
    dog = Dog()  # 实例化
    dog.sleep()
    dog.eat()  # 在类外部实例化后调用
View Code

  输出结果:    

    狗狗吃饭
    狗狗睡觉
    狗狗吃饭 

2、类方法

定义:无需对类进行实例化便可调用的方法,默认传参类本身,有修饰符@classmethod

语法:

  @classmethod

  def 方法名(cls):

    方法体

调用:

  在类外部:类.方法名()  或  实例.方法名()

  在类内部:self.方法名()

例子:

class Dog:
    # 类方法
    @classmethod
    def eat(cls):
        print('狗狗吃饭')

    # 实例方法
    def sleep(self):
        self.eat()  # 在类内部调用eat类方法
        print('狗狗睡觉')


if __name__ == '__main__':
    Dog.eat()  # 类调用类方法
    dog = Dog()
    dog.eat()  # 实例调用类方法
    dog.sleep()
View Code

  输出结果:    

    狗狗吃饭
    狗狗吃饭
    狗狗吃饭
    狗狗睡觉

3、静态方法

定义:无需对类进行实例化便可调用的方法,且默认无需传参,有修饰符@staticmethod

语法:

  @staticmethod

  def 方法名():

    方法体

调用:

  在类外部:类.方法名()  或  实例.方法名()

  在类内部:self.方法名()

例子:

class Dog:
    # 静态方法
    @staticmethod
    def eat():
        print('狗狗吃饭')

    # 实例方法
    def sleep(self):
        self.eat()  # 在类内部用实例本身调用eat静态方法
        print('狗狗睡觉')


if __name__ == '__main__':
    Dog.eat()  # 在类外部用类本身调用静态方法
    dog = Dog()
    dog.eat()  # 在类外部用实例调用静态方法
    dog.sleep()
View Code

  输出结果:

    狗狗吃饭
    狗狗吃饭
    狗狗吃饭
    狗狗睡觉 

注:静态方法和类方法相似,不同点在于静态方法默认无需传参,类方法默认传参类本身。另外,静态方法没有用到类的属性和其它方法,所以,静态方法和当前类的相关性很低,某些情况下可以作为独立的函数独立出来。

4、私有方法

定义:方法名称前面是双下划线,仅类内部可进行调用,类外部无法访问,传参实例本身,无修饰符

语法:

  def __方法名(self):  # 注意方法名前面是两条下划线

    方法体

调用:

  在类内部:self.__方法名()

例子:

class Test:
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

    def __test01(self):
        return self.num1 + self.num2

    def __test02(self):
        return self.num1 * self.num2

    def test03(self):
        print('相加的结果是:', self.__test01())
        print('相乘的结果是:', self.__test02())


if __name__ == '__main__':
    test = Test(3, 5)
View Code

  输出结果:

    相加的结果是: 8
    相乘的结果是: 15

使用场景:私有方法一般作为实例方法的辅助作用,不对外展示。

二、类的特性

1、封装

定义:隐藏功能实现的内部细节,对外仅提供接口,传递必要的参数即可实现想要的结果,就称为封装。例如函数、类等都是封装的一种,生活中的封装如取款机、计算器等也是封装。

2、继承

(1)单继承

定义:子类仅继承一个父类,子类无需重新定义父类的属性和方法便拥有了父类的属性和方法(私有属性和私有方法除外),这就是单继承。

语法:

  class Father:

    父类的属性和方法体

  class Son(Father):

    pass

例子:

class Father:
    money = '100万'
    __myself = '衣服'

    def drive(self):
        print('我会开车')

    def __fly_a_plane(self):
        print('我会开飞机')


class Son(Father):  # Son类继承了Father类的money属性和drive方法,私有属性__myself和私有方法__fly_a_plane无法继承
    pass


if __name__ == '__main__':
    son = Son()
    print(f'我有{son.money}')  # 可以访问父类的money属性
    son.drive()  # 可以调用父类的drive方法
View Code

  输出结果:

    我有100万
    我会开车

初始化:子类在实例化后,会自动执行子类的初始化方法,若子类没有初始化方法,则会从父类中调用初始化方法并执行

class Father:
    def __init__(self):
        print('父类的初始化方法')


class Son(Father):
    pass


if __name__ == '__main__':
    Son()  # 子类实例化自动执行初始化方法,由于子类没有初始化方法,所以调用父类的初始化方法
View Code

  输出结果:

    父类的初始化方法

方法调用:子类调用一个方法时,若子类若和父类同时存在该方法,调用时优先调用子类自己的方法,如果子类不存在该方法,则调用父类的方法。

class Father:
    def reading(self):
        print('父类的阅读方法')


class Son(Father):
    def reading(self):
        print('子类的阅读方法')


if __name__ == '__main__':
    Son().reading()
View Code

  输出结果:

    子类的阅读方法

如果想跳过子类的同名方法直接调用父类方法,可在子类中定义一个新的方法,然后用关键字super()调用即可

class Father:
    def reading(self):
        print('父类的阅读方法')


class Son(Father):
    def reading(self):
        print('子类的阅读方法')

    def test(self):
        self.reading()  # 调用子类自己的reading方法
        super().reading()  # super()关键字调用父类的reading方法


if __name__ == '__main__':
    Son().test()
View Code

  输出结果:

    子类的阅读方法
    父类的阅读方法

继承的使用场景:1)需要使用父类的方法,避免重复实现;2)对父类的方法进行重写;3)对父类的方法进行拓展

重写和拓展案例:

class Father:
    def reading(self):
        print('父类在家阅读')


class Son(Father):
    def reading(self):
        print('子类在图书馆阅读')  # 修改父类的reading方法

    def study(self):
        # 在父类方法基础上进行拓展,不过这个并没有改变父类的方法,与其说拓展,不如说直接就是调用也可以
        super().reading()
        print('我给他倒了一杯茶')


if __name__ == '__main__':
    Son().reading()
    Son().study()
View Code

  输出结果:

    子类在图书馆阅读
    父类在家阅读
    我给他倒了一杯茶

(2)多继承

定义:子类继承超过一个父类,子类无需重新定义父类的属性和方法便拥有了多个父类的属性和方法(私有属性和私有方法除外),这就是多继承。

语法:class 子类(父类1,父类2····)

例子:

class Test01:
    attr01 = 'Test01的属性'

    def test01(self):
        return 'Test01的方法'


class Test02:
    attr02 = 'Test02的属性'

    def test02(self):
        return 'Test02的方法'


class Test(Test01, Test02):
    pass


if __name__ == '__main__':
    test = Test()
    res1 = test.test01()
    res2 = test.test02()
    print(test.attr01, res1, test.attr02, res2)
View Code

  输出结果:

    Test01的属性 Test01的方法 Test02的属性 Test02的方法

方法调用:(方法查找顺序)self从子类自己开始查找,然后父类从左到右顺序;super()是从父类开始查找,也是从左到右顺序

例子:

class Test01:
    def test(self):
        return 'Test01的方法'


class Test02:
    def test(self):
        return 'Test02的方法'

    def test02(self):
        return 'Test02 === 方法'


class Test(Test01, Test02):
    def test(self):
        return 'Test的方法'

    def test02(self):
        return 'Test === 方法'

    def test01(self):
        res1 = self.test()  # 子父类有同名方法,用self直接调用自己重写后的方法(查询顺序从子类自己开始,所以调用的是子类自己重写后的方法)
        res2 = super().test()  # 子父类有同名方法,用super()调用首个父类同名的方法(这里虽然Test01和Test02都有同名方法,查找顺序从左到右所以是调用Test01的同名方法)
        res3 = super().test02()  # 子父类有同名方法,用super()调用首个和父类同名的方法(这里Test01没有此同名方法,查找顺序从左到右所以是调用Test02的同名方法)
        return res1, res2, res3


if __name__ == '__main__':
    test = Test()
    res = test.test01()
    print(res)
View Code

  输入结果:

    ('Test的方法', 'Test01的方法', 'Test02 === 方法')

MRO表:表示类与类之间继承关系的图标(Pycharm专业版可见)
多继承原则:不要互相继承

3、多态【了解,在Python中多态不严谨】

posted @ 2021-07-18 20:31  阿炳~  阅读(346)  评论(0)    收藏  举报