Python继承

一、继承

Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法。

1.单继承
class A(object):
    def __init__(self):
        self.num = 1

    def print_info(self):
        print(self.num)
class B(A):
    pass
b = B()
b.print_info()

在Python中,所有的类默认继承object类,object类是顶级类或基类;其他子类叫做派生类。

2. 多继承

所谓的多继承意思是一个类同时继承了多个父类。

class Master(object):
    def __init__(self):
        self.kongfu = "煎饼果子技术"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")


class School(object):
    def __init__(self):
        self.kongfu = "黑马煎饼果子"

    def make_cake(self):
        print(f"运用了{self.kongfu}制作煎饼果子")


class Pretice(School, Master):
    pass


p = Pretice()
print(p.kongfu)
p.make_cake()

注意:当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法。

3. 子类重写父类同名属性和方法

如果子类和父类拥有同名属性和方法,默认使用子类里面的同名属性和方法。

4. 子类调用父类同名属性和方法
class Master(object):
    def __init__(self):
        self.kongfu = "古法煎饼果子技术"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")


class School(object):
    def __init__(self):
        self.kongfu = "黑马煎饼果子"

    def make_cake(self):
        print(f"运用了{self.kongfu}制作煎饼果子")


class Pretice(School, Master):
    def __init__(self):
        self.kongfu = "独创煎饼果子"

    def make_cake(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化,kongfu属性值是上一次调用的init内的kongfu的值
        self.__init__()
        print(f"运用了{self.kongfu}制作煎饼果子")

    # 子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装
    def make_master_cake(self):
        # 父类类名.函数()
        # 再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)


p = Pretice()
p.make_master_cake()
p.make_school_cake()
p.make_cake()
print(Pretice.__mro__)  # 查看类的继承关系
5. 多层继承
class Master(object):
    def __init__(self):
        self.kongfu = "古法煎饼果子技术"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")


class School(object):
    def __init__(self):
        self.kongfu = "黑马煎饼果子"

    def make_cake(self):
        print(f"运用了{self.kongfu}制作煎饼果子")


class Pretice(School, Master):
    def __init__(self):
        self.kongfu = "独创煎饼果子"

    def make_cake(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化,kongfu属性值是上一次调用的init内的kongfu的值
        self.__init__()
        print(f"运用了{self.kongfu}制作煎饼果子")

    # 子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装
    def make_master_cake(self):
        # 父类类名.函数()
        # 再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)


class TuSun(Pretice):
    pass

p = TuSun()
p.make_cake()
p.make_master_cake()
p.make_school_cake()
print(Pretice.__mro__)  # 查看类的继承关系
6. supper()调用父类方法
class Master(object):
    def __init__(self):
        self.kongfu = "古法煎饼果子技术"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")

class School(Master):
    def __init__(self):
        self.kongfu = "黑马煎饼果子"

    def make_cake(self):
        print(f"运用了{self.kongfu}制作煎饼果子")
        # super(School, self).__init__()
        # super(School, self).make_cake()
        # 2.2 无参数
        super().__init__()
        super().make_cake()

class Pretice(School):
    def __init__(self):
        self.kongfu = "独创煎饼果子"

    def make_cake(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化,kongfu属性值是上一次调用的init内的kongfu的值
        self.__init__()
        print(f"运用了{self.kongfu}制作煎饼果子")

    # 子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装
    def make_master_cake(self):
        # 父类类名.函数()
        # 再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

    def make_old_cake(self):
        # 方法一:如果定义类名修改,这里也需要修改,麻烦,代码量庞大,冗余
        # School.__init__(self)
        # School.make_cake(self)
        # Master.__init__(self)
        # Master.make_cake(self)
        # 方法二:supper
        # 2.1 supper(当前类名, self).函数()
        # super(Pretice, self).__init__()
        # super(Pretice, self).make_cake()
        # 2.2 无参数
        super().__init__()
        super().make_cake()

p = Pretice()
p.make_old_cake()

注意:使用supper()可以自动查找父类。调用顺序遵循__mro __类属性的顺序,比较适合单继承的使用。

二、私有权限

1. 定义私有属性和方法

在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或方法不继承给子类。
设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __。

class A(object):
    def __init__(self):
        self.name = "张飞"
        self.age = 36
        self.__salary = 8000
    def print_info(self):
        print(f"{self.name}, {self.age}, {self.__salary}")

class B(A):
    pass

b = B()
print(b.print_info())

注意:私有属性和私有方法只能在类里面访和修改

2. 获取和修改私有属性

在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值。

class A(object):
    def __init__(self):
        self.name = "张飞"
        self.age = 36
        self.__salary = 8000
    def print_info(self):
        print(f"{self.name}, {self.age}, {self.__salary}")

    # 获取私有属性值
    def get_money(self):
        return self.__salary
    
    # 设置私有属性值
    def set_money(self, salary):
        self.__salary = salary

class B(A):
    pass

b = B()
print(b.get_money())
b.set_money(10000)
print(b.get_money())

你可能感兴趣的:(Python基础/进阶,python,类)