python入门(8)—— 对象的继承,重写方法,多态,静态

1.继承的格式

"""
继承:
    子类继承父类,子类一旦继承父类,就拥有父类中非私有的属性和方法.
继承的格式:
    class 子类名(父类名):
        子类中的代码

继承的好处:
    1.避免了代码重复,提高了代码的重复使用率.
    2.扩展了子类的功能.

"""
class Father:
    def __init__(self,money,address):
        self.money = money
        self.address = address
    def run_company(self):
        print("父亲运营公司。。。")
class Son(Father):
    pass

son = Son(2000000000,"北京市前门大街100号")
print(son.address) # 北京市前门大街100号
print(son.money)   # 2000000000
son.run_company()  # 父亲运营公司。。。

2.object类介绍

obj = object()

# class Student:
#     pass
# 等价于下面的写法
class Student(obj):
    pass
s = Student()

3.子类不能继承父类中的私有方法和属性

"""
3.子类不能继承父类中私有的属性和方法
"""
class Father:
    def __init__(self,money,address):
        self.money = money
        self.address = address
        self.__food = "油条"
    def run_company(self):
        print("父亲运营公司。。。")
    def __eat(self):
        print(f"父亲只喜欢{self.__food}")

class Son(Father):
    def test(self):
        print("获取父亲的饮食爱好")
        self.__eat()

s = Son(2000000,"北亭大街1000号")
print(s.money)   # 2000000
print(s.address) # 北亭大街1000号
s.run_company()  # 父亲运营公司。。。
# s.__eaa() # AttributeError: 'Son' object has no attribute '__eaa'
# s.test() # AttributeError: 'Son' object has no attribute '_Son__eat'

4.子类中重写父类的方法

"""
重写父类中的方法的原因:
    父类中的方法不能满足子类的需要,但是子类又想保留这个方法名.
重写父类中的方法:
    这就需要在子类中定义一个同名的方法,这叫重写父类中的方法.
如何重写:
    1.把父类中的方法复制粘贴到子类中
    2.在子类中修改方法体

特点:
    子类重写了父类中的方法后,当通过子类对象调用这个方法时,调用的是子类中的这个方法.
"""
class Father:
    def __init__(self,money,address):
        self.money = money
        self.address = address
        self.__food = "油条"
    def run_company(self):
        print("父亲运营公司。。。")
class Son(Father):
    def run_company(self):
        print("儿子来运营公司了。。。")

s = Son(200000,"东直门大街50号")
s.run_company()  # 儿子来运营公司了。。。

5.子类调用父类中被重写的方法

"""
调用 父类中的被重写的run_company方法,有三种格式:
    1.父类名.方法名(self, 实参1,实参2,...)
    2.super(子类名,self).方法名(实参1,实参2,...)
    3.super().方法名(实参1,实参2,...)
"""
class Father:
    def __init__(self,money,address):
        self.money = money
        self.address = address
        self.__food = "油条"
    def run_company(self):
        print("父亲运营公司。。。")

# 子类继承父类
class Son(Father):
    # 重写了父类中的run_company方法
    def run_company(self):
        print("儿子来运营公司了。。。")
    # 假如子类中还希望使用父类中的方法,可以这么做
    def test(self):
        # 调用的是子类中的run_company方法
        # self.run_company()

        # 调用 父类中的run_company方法
        # 1.父类名.方法名(self, 实参1,实参2,...)
        # Father.run_company(self)
        # 2.super(子类名,self).方法名(实参1,实参2,...)
        # super(Son, self).run_company()
        # 3.super().方法名(实参1,实参2,...)
        super().run_company()

s = Son(200000,"东山区10号")
s.run_company()  # 儿子来运营公司了。。。
s.test()         # 父亲运营公司。。。

6.继承中的两个细节——获取父类的私有属性、方法

# 子类可以通过访问父类中的公有方法,获取父类私有的属性和方法
class Father:
    def __init__(self,money,address):
        self.money = money
        self.address = address
        # 私有属性
        self.__food = "tomato"
    def run_company(self):
        print("父亲运营公司...")
    # 私有方法
    def __my_hobby(self):
        print(f"父亲喜欢吃{self.__food}")
    def test(self):
        print("儿子想知道父亲的爱好是:",end="  ")
        self.__my_hobby()
# 子类继承父类
class Son(Father):
    def la(self):
        self.test()

s = Son(200000,"北直街11号")
s.test() # 儿子想知道父亲的爱好是:  父亲喜欢吃tomato
s.la()   # 儿子想知道父亲的爱好是:  父亲喜欢吃tomato

7.继承中的两个细节——使用super()关键字继承父类的__init__方法

# 使用super()关键字继承父类的__init__方法
class Father:
    def __init__(self,money,addr):
        self.money = money
        self.addr = addr
    def run_company(self):
        print("父亲经营公司。。。")

class Son(Father):
    # 重写父类的__init__方法
    def __init__(self,name,money,addr):
        self.name = name
        # 使用第三种格式调用父类中的__init__方法
        super().__init__(money,addr)

s = Son("聪聪",22,"北直街10号")
print(s.name)
print(s.addr)
print(s.money)

8.多层继承

"""
多层继承:
    一层一层的继承;

就是单继承.
"""
class A:
    def __init__(self,a):
        self.a = a
    def methodA(self):
        print("--------methodA---------")

class B(A):
    def __init__(self,a,b):
        self.b = b
        super().__init__(a)
    def methodB(self):
        print("--------methodB---------")
    # def methodA(self):
    #     print("--------methodA---------")

class C(B):
    def __init__(self,a,b,c):
        self.c = c
        super().__init__(a,b)
    def methodC(self):
        print("--------methodC---------")
    # def methodB(self):
    #     print("--------methodB---------")
    # def methodA(self):
    #     print("--------methodA---------")

c = C("AAA","BBB","CCC")
c.methodA()  # --------methodA---------
c.methodB()  # --------methodB---------
c.methodC()  # --------methodC---------

print(c.a)   # AAA
print(c.b)   # BBB
print(c.c)   # CCC

9.多继承

"""
多继承的格式:

    class 子类名(父类1, 父类2, ...):
        子类中的代码
"""
class A:
    def __init__(self,a):
        self.a = a
    def methodA(self):
        print("methodA")
    def show(self):
        print("A-show")
class B:
    def __init__(self,b):
        self.b = b
    def methodB(self):
        print("methodB")
    def show(self):
        print("B-show")
# 让C类同时继承A,B两个父类
class C(A, B):
    # 为了继承A,B两个父类中的属性,需要重写init方法,在方法中调用两个父类中的init方法
    def __init__(self,a,b):
        A.__init__(self,a)  # 注意调用父类__init__方法
        B.__init__(self,b)  # 注意调用父类__init__方法

c = C("AAA","BBB")
print(c.a)  # AAA
print(c.b)  # BBB

c.methodA() # methodA
c.methodB() # methodB
c.show()    # A-show

10.多继承-调用父类中的方法

"""
多继承的格式:

    class 子类名(父类1, 父类2, ...):
        子类中的代码
多继承中调用父类的方法:
    父类名.父类方法
"""
class A:
    def __init__(self,a):
        self.a = a
    def methodA(self):
        print("methodA")
    def show(self):
        print("A-show")
class B:
    def __init__(self,b):
        self.b = b
    def methodB(self):
        print("methodB")
    def show(self):
        print("B-show")
# 让C类同时继承A,B两个父类
class C(A, B):
    # 为了继承A,B两个父类中的属性,需要重写init方法,在方法中调用两个父类中的init方法
    def __init__(self,a,b):
        # 调用A,B类中的init方法
        A.__init__(self,a)  # 注意调用父类__init__方法
        B.__init__(self,b)  # 注意调用父类__init__方法
    # 指定调用指定父类中的方法
    def test(self):
        # 调用A类中的方法有两种
        self.show()
        A.show(self) # 注意括号里边的self参数必须传过去给父类!
        # 调用B类中的方法就只有一种
        B.show(self)
c = C("AAA","BBB")
c.test()

c = C("AAA","BBB")

11.类属性

"""
类属性:
    也是 一种 属性.
    它存储的数据,是所有的实例对象共享共用的数据,在内存中只有一份,不属于某一个实例对象专有.是所有的实例对象共有的.

    当某一个数据 是所有的实例对象共享共用时,才使用 一个类属性 存储这个数据.

定义类属性的格式:
    在类的里面,方法的外面定义.

类属性的访问方式:
    1. 实例对象名.类属性名
    2. 类名.类属性名(推荐)

修改类属性:
    类属性只能通过类对象(类名)修改.
    不能通过实例对象修改.
"""
class Student:
    # 定义类属性
    # kongtiao = "格力空调"
    # 类属性也可以定义成私有的,私有的类属性不能在类的外面访问,只能在类的里面访问
    # 定义格式:在类属性前面加两个 下划线.
    __kongtiao = "格力空调"

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

    def study(self):
        # 1. 实例对象名.类属性名
        # print(self.kongtiao)
        # 通过实例对象修改类属性
        # 当通过实例对象修改类属性时,并不是真正修改类属性,而是定义一个同名实例属性,
        # 以后通过实例对象访问这个属性时访问的是实例属性.
        self.__kongtiao = "海尔空调"
        print(self.__kongtiao)
        # 2. 类名.类属性名
        # print(Student.kongtiao)
        #Student.__kongtiao = "美的空调"
        print(Student.__kongtiao)
        print("哈哈哈........")

s = Student("冬冬", 29, "女")
#
s.study()
#
# # 1. 实例对象名.类属性名
# print(s.kongtiao)
# 2. 类名.类属性名
# print(Student.kongtiao)

# 私有的类属性不能在类的外面访问,只能在类的里面访问
# print(Student.__kongtiao)

12.类方法

"""
    定义类方法:
        1.在方法定义的那一行的上面,使用@classmethod装饰器
            这个装饰器的作用:
                1.用来表示下面的方法是一个类方法的
                2.在调用类方法时,python解释器会自动把类名传递cls
        2.第一个形参必须是cls,表示类对象,就是那个类名

    访问方式:
        1.实例对象.类方法名(实参1,实参2,...)
        2.类对象.类方法名(实参1,实参2,...)(推荐的方式)
    特点:
        1.在调用类方法时,python解释器会自动把类对象传递给cls
        2.只能访问类属性或者类方法,不能访问实例属性或者实例方法

    什么时候定义一个类方法?
        在方法中只需要访问类属性或者类方法,不访问实例属性或者实例方法.
"""
class Student:
    __kongtiao = "格力空调"
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

    @classmethod
    def study(cls):
        print(cls.__kongtiao)
        cls.show()
    @classmethod
    def show(cls):
        print("我正在学习。。。")

# 1.实例对象.类方法名(实参1,实参2,...)
s = Student("张三",24,"male")
s.study()
# 2.类对象.类方法名(实参1,实参2,...)
Student.study()

13.静态方法

先定义一个带静态方法的类

class EncodingUtil:
    @staticmethod
    def encode(data,charset):
        print("加密。。。")
    @staticmethod
    def decode(data,charset):
        print("解密...")
# EncodingUtil.encode("hello","UTF-8")
# # EncodingUtil.decode("hello","UTF-8")

调用静态方法:

import jingtai

class Student:
    __kongtiao = "格力空调"

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

    """
    定义静态方法的步骤:
        1.在方法定义的那一行的上面,使用@staticmethod装饰器
            1.标识下面的方法时静态方法
        2.方法的第一个形参,既不是self也不是cls.

    特点:
        在方法中不能访问实例属性和实例方法了,因为在它里面得不到self
        通常在这个方法中不访问实例属性和实例方法也不访问类属性和类方法.

    访问方式:
         1.实例对象.类方法名(实参1,实参2,...)
         2.类对象.类方法名(实参1,实参2,...)(推荐的方式)

    在什么时候定义静态方法?
        当在这个方法中既不访问实例属性实例方法,也不访问类属性类方法时.
    """

    @staticmethod
    def study():
        print("挖掘技术哪家强,")
        print("欲学技术到蓝翔.")
        print("学完技术包分配,")
        print("尼玛还是富士康!")

    def test(self):
        jingtai.EncodeUtils.encode("hello", "utf-8")
        self.study()
        Student.study()


# 1.实例对象.类方法名(实参1,实参2,...)
s = Student("张柏芝", 38, "女")
# s.study()
# Student.study()
s.test()

15.多态

class Father:
    def cure(self):
        print("父亲在治病...")
class Son(Father):
    def cure(self):
        print("儿子在治病...")

def call_cure(doctor):
    # 调用医生的治病方法
    doctor.cure()

# 创建父类对象
f = Father()
call_cure(f)

s = Son()
call_cure(s)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值