• 【python基础语法】继承、反射机制和面向对象编程(下)(第11天课堂笔记)


    '''
    继承:
    
    1、类方法、静态方法、私有属性
    
    类方法:使用装饰器@classmethod,第一个参数必须是当前类的对象,该参数名一般约定为"cls",
    通过它来传递类的属性和方法(不能传实例的属性和方法),"cls"代表类本身
    类方法调用:实例对象和类对象都可以调用
    实例方法:只能由实例对象来调用
    应用场景:需要站在类的角度执行某个行为时,那么就应该定义为类方法
    
    静态方法(了解即可):
    定义:使用装饰器@staticmethod,参数随意,没有"self"和"cls"参数,
    但是方法体中不能使用类或者实例的任何属性和方法
    调用:实例对象和类对象都可以调用
    应用场景:存放逻辑代码,内部不需要引用类属性和实例属性
    
    私有属性(了解即可):
    单下划线开头:_attr
    双下滑开头:__attr
    声明为私有属性:声明为私有属性,那么该说明属性是类私有的,仅限于在类里面使用,
    不要在类外面去调用(实际上类外面可以访问,讨论这个毫无意义)
    
    2、类的继承关系
    什么是继承,继承有什么作用?
    面向对象编程中有一个重要的思想叫继承,子类通过继承可以获得父类的属性和方法,
    被继承的类叫做父类(基类),继承的类叫子类
    作用:子类通过继承可以获得父类的属性和方法,提高开发的效率及代码的复用率
    类的两种定义方式:
    方式一:
    class 类名:
        pass
    方式二:
    class 类名(继承的父类):
        pass
    object:是所有类的顶级父类(基类)
    
    类属性可以直接继承
    实例方法通过继承可以得到
    
    实例属性能不能继承?
    实例属性是每个实例对象所独自有的,不是通过继承得到的
    继承是针对类而言的,只有类里面的东西才能被继承
    创建实例对象的时候才会进行赋值
    
    将有限的时间和精力花在当前我们紧急要做的事情上面
    在最短的时间用python去做自动化,而不是研究底层原理和高阶编程
    
    3、重写父类方法
    重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖父类中同名的方法
    直接调用重写之后的方法,直接调用自身有的这个方法(不会去父类找)
    在方法中调父类被重写的方法:
    方式一:父类名.方法名
    方式二:super().方法名()
    
    扩展:
    ___new__方法:创建对象
    Create and return a new object
    
    面向对象的三大特征:
    继承:
    封装:将变量定为类属性和相似功能的函数(方法)进行封装
    多态:鸭子类型
    
    4、调用重名的父类方法
    子类重写了父类的方法之后,如何在子类中再调用父类的方法?
    方式一:父类.方法名(self)
    方式二:super().方法名()
    
    5、属性动态设置(反射机制)
    setattr:设置属性
    getattr:获取属性
    delattr:删除属性
    
    总结:
    万物皆对象
    
    函数:函数对象
    基本数据:str list
    类:类对象
    模块(文件):模块对象
    包:包对象
    自定义类创建出来的对象
    
    '''
    """
    特征(属性):血量(HP) 蓝量(XP) 攻击力(attack) 暴击率
    行为(方法):技能1 技能2 技能3 移动
    总结:类的定义、属性、方法,self的含义,初始化方法
    
    问题需求:
    需求V1:实现一个初始版的手机类(大哥大)
    只能打电话
    需求V2:实现一个定义功能机类
    打电话、听音乐、发短信
    需求V3:实现一个智能手机类
    打电话、听音乐、发短信、看视频、玩游戏、手机支付、视频通话
    
    """
    class Hero:
        def __init__(self,name,HP):
            self.name = name
            self.HP = HP
            print("自动调用了---init---方法,完成实例对象的初始化")
        def move(self):
            print("走向战场")
        def skill(self):
            print("使用了技能砍一刀")
    
    class MyClass:
        # 定义类属性
        attr = 100
        # 私有属性(声明为私有属性之后,不要在类外面通过类或者对象去使用这个属性)
        _attr = 999
        __attr = 99999
        # 定义实例属性
        def __init__(self,name,age):
            self.name = name
            self.age = age
        # 定义实例方法
        def func1(self):
            print("实例方法1")
        # 定义类方法@classmethod
        @classmethod
        def c_func(cls):
            print("类方法c_func")
        # 静态方法,将函数定义到类里面来,可以定义为静态方法
        @staticmethod
        def s_func():
            print("这个是静态方法")
    
    # # 创建一个m对象,并给m对象赋值
    m = MyClass("hc",18)
    # # 调用实例方法(类无法调用实例方法,例如:MyClass.func1())
    # m.func1()
    #
    # # 对象调用类方法
    m.c_func()
    # 类调用类方法
    MyClass.c_func()
    
    # 静态方法的调用
    MyClass.s_func()
    m.s_func()
    
    # 类的两种定义方式:
    # 如果不写继承的父类(默认也是继承于object)
    class Myclass:
        pass
    # 可以自己指定继承的父类
    class MyClassA(object):
        pass
    
    # 继承关系,举例
    class BasePhone(object):
        """大哥大"""
        # basephone手机的类属性
        attr = "红色"
        # 定义实例属性,是独有的,需要传参数
        def __init__(self,name):
            self.name = name
        # 定义实例方法,不是独有的,无需传参
        def call_phone(self):
            print("打语音电话base")
    
    # Phone_V1继承BasePhone所有功能
    class Phone_V1(BasePhone):
        # 功能机
        def call_phone(self):
            print("打语音电话v1")
        def send_msg(self):
            print("发短信功能")
        def music(self):
            print("听音乐")
    
    class Phone_v2(Phone_V1):
        """智能机"""
        # 重写父类的方法,更新和升级父类方法
        # 父类有一个方法,继承之后定义了一个和父类方法名相同的方法
        def call_phone(self):
            print("拨打视频电话")
            print("时间过去了5分钟再转成语音通话")
            # 在方法中调用父类被重写的方法
            # 方式一:类名.方法名(self)
            # 通过类调用实例方法,self必须自己传参
            BasePhone.call_phone(self)
            # 方式二:super().方法名()
            super().call_phone()
        def game(self):
            print("玩游戏")
        def qq(self):
            print("聊QQ")
    
    xm = Phone_v2("华为P30")
    # 访问继承的实例方法
    xm.call_phone()
    xm.send_msg()
    xm.game()
    # 调用父类的实例属性
    print(xm.name)
    # 访问继承的属性
    print(Phone_v2.attr)
    
    b1 = BasePhone("大哥大")
    v1 = Phone_V1("oppo音乐手机")
    p1 = Phone_v2("华为P30")
    
    print(p1.name)
    print(b1.name)
    print(v1.name)
    
    # 重写父类的call_phone方法后子类调用父类的方法
    v2 = Phone_v2("华为P30")
    # 直接调用重写之后的方法,直接调用自身有的这个方法(不会调用父类的方法)
    v2.call_phone()
    
    # 重写父类方法的应用场景
    class Obj(object):
        # 重写new方法
        # 第一种调用new方法的方式,自己创建的new方法无法创建对象,需要借用父类的
        def __new__(cls,*arg,**kwargs):
            # object.__new__(cls)
        # 第二种:
            res = super().__new__(cls)
            return res
    # 通过类名创建对象,没有重写new方法,默认调用object类中的new方法
    o = Obj()
    print(o)
    
    # 属性动态属性(反射机制):
    class Cases:
        def __init__(self,name):
            self.name = name
    
    case1 = Cases("111")
    datas = {"case_id":1,"data":"999","url":"www.baidu.com"}
    # 对象.属性名 = 属性值
    # setattr:设置属性
    # 给对象动态设置属性:参数(对象,属性名,属性值)
    setattr(case1,"age",99) # 等同于:case1.age = 99
    print(case1.age)
    for k,v in datas.items():
        print(k,v,type(k),type(v))
        # case1.k = v
        setattr(case1,k,v)
    print(case1.url)
    
    # getattr:获取属性
    res = getattr(case1,"name")
    print(res)
    # delattr:删除属性
    res = delattr(case1,"name")
    print(res)
  • 相关阅读:
    【转载】理解本真的REST架构风格
    Linux常用命令
    使用MongoDB存储集合的一些问题
    AutoMapper快速上手
    JavaScript instanceof 运算符深入剖析
    使用c#对MongoDB进行查询(1)
    centos7安装rabbitmq3.7.9
    nginx1.14.0版本高可用——keepalived双机热备
    nginx1.14.0版本https加密配置
    nginx1.14.0版本负载均衡upstream配置
  • 原文地址:https://www.cnblogs.com/python-test001/p/12397693.html
Copyright © 2020-2023  润新知