zoukankan      html  css  js  c++  java
  • 面向对象进阶

    1. 绑定方法和非绑定方法

    绑定方法 对象绑定方法/类的绑定方法

    绑定方法:特殊之处,绑定给谁就是谁来调,并且会把自身传过来

    类的绑定方法:绑定给类的,类来调用,会把类自身传过来

    类的绑定方法用在什么地方:不需要通过对象,只需要通过类就能获取到一些东西的时候

    类的绑定方法可以用对象来调

    class Person:
        def __init__(self,name,age):
            print(self)
            self.name = name
            self.age = age
        @classmethod
        def test(cls):
            print(cls)
            print('类的绑定方法')
            # 类实例化产生对象,返回
            return cls('lqz',19)
    
    Person.test()
    
    Person('nick',18)
    
    class Admin:
        def __init__(self,name,age):
            print(self)
            self.name = name
            self.age = age
        @classmethod
        # 类的绑定方法
        def get_obj_by_name(cls,name):
            # 取到类的名字
            type_class = cls.__name__.lower()
            # 1 去文件中查找名字为name的pickle文件
            # 2 序列化成对象
            # 3 return 对象
            pass
        # 对象的绑定方法
        def get_obj_by_name1(self,name):
            # 1 去文件中查找名字为name的pickle文件
            # 2 序列化成对象
            # 3 return 对象
            pass
    
    # 类
    admin = Admin.get_obj_by_name('lqz')
    
    admin = Admin.get_obj_by_name1(None,'lqz')
    # 对象
    admin = Admin('nick',19)
    admin1 = admin.get_obj_by_name('lqz')
    
    
    # 类的绑定方法可以用对象来调
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        @classmethod
        def test(cls):
            print(cls)
            print('类的绑定方法')
    
    # Person.test()
    p = Person('nick',18)
    # 对象可以调用类的绑定方法,也是把该对象的类传入
    p.test()
    
    '''
    总结:
        classmethod 是个装饰器,放在类中的函数上面,该函数就变成了类的绑定方法
        类的绑定方法由类来调用,自动把类传过去(对象也可以调,一般不用)
        类的绑定方法用在什么地方?
        不需要通过对象,只需要通过类就能完成某些事的时候,就把该方法定义为类的绑定方法
    '''
    

    2. staticmethod 非绑定方法

    staticmethod 非绑定方法,定义在类内部,普通方法,谁都不绑定

    对象/类都可以调用,但是不会自动传值

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def object_method(self):
            print('我是对象绑定方法,对象来调用我')
    
        @classmethod
        def class_method(cls):
            print('我是类的绑定方法,类来调用我')
    
        # 当成一个普通函数,只不过是写在类内部的
        @staticmethod
        def static_method():
            print('我是静态方法,谁都不绑定')
    
    # 静态方法(非绑定方法)
    # 类来调用
    Person.static_method()
    # 对象来调用
    p = Person('nick',19)
    p.static_method()
    
    '''
    # 生成一个唯一的id号
    import uuid
    print(uuid.uuid4())
    '''
    
    # 静态方法(非绑定方法)的作用
    # 跟类和对象都没有关系的时候,可以定义成静态方法,一般在类内部使用,类外部也可以使用
    # 就是一个普通函数,想把它拿到类中管理,就可以定义成静态方法
    
    class Person:
        def __init__(self,name,age):
            self.id = self.get_uuid()
            self.name = name
            self.age = age
    
        # 当成一个普通函数,只不过是写在类内部的
        @staticmethod
        def static_method():
            print('我是静态方法,谁都不绑定')
        @staticmethod
        def get_uuid():
            import uuid
            return uuid.uuid4()
    
    import uuid
    def get_uuid():
        return uuid.uuid4()
    a = uuid.uuid4()
    # p = Person(uuid.uuid4(),'nick',18)
    # p = Person(get_uuid(),'nick',18)
    p = Person('nick',18)
    print(p.id)
    print(Person.get_uuid())
    # 面向对象高级:Person类也是一个特殊的对象
    

    3. 面向对象串讲

    # 面向对象最本质解决的是:提供可扩展性
    # 类与对象
    # 程序中必须先有类,再有对象
    
    # 类中有属性,有方法
    class Person:
        # 类属性
        school = 'oldboy'
        count = 0
        # 对象的绑定方法,初始化方法完成对象的初始化
        # 特殊之处,类实例化的时候自动调用
        def __init__(self,name='lqz'):
            Person.count += 1
            self.name = name
            self.age = 19
    p = Person('nick')
    # 对象是不能修改类属性的
    # 类属性只能类来修改
    print(Person.__dict__)
    p.school = 'ppp'
    print(p.__dict__)
    # 绑定方法
    # 定义在类内部,没有装饰器装饰的方法都是对象的绑定方法
    # 需要对象来调用,对象调用的时候,会把自身传入
    class Person:
        def __init__(self,name='lqz'):
            self.name = name
            self.age = 19
        def change_name(self,name):
            self.name = name
    
    p = Person()
    p.change_name('xxx')
    # 本质就是  Person.change_name(p,'xxx')
    
    # 对象交互
    class Person:
        def __init__(self,name='lqz'):
            self.name = name
            self.age = 19
        def change_name(self,name):
            self.name = name.upper()
    
    # 继承
    # 减少代码冗余
    # 选课系统,每个类应该有两个方法
    # 方法一:根据名字获取对象
    # 方法二:保存对象自身的功能
    import pickle
    import os
    class BaseClass:
        @classmethod
        def get_obj_by_name(cls,name):
            # 字符串
            # admin
            class_name = cls.__name__.upper()
            # 文件路径
            path = os.path.join(class_name,name)
            with open(path,'rb') as f:
                obj = pickle.load(f)
            return obj
    
        def save(self):
            # 对象拿到类self.__class__
            cls = self.__class__
            class_name = cls.__name__.lower()
            #
            path = os.path.join(class_name,self.name)
            with open(path,'wb') as f:
                pickle.dump(self,f)
            return True
    
    
    class Admin(BaseClass):
        def register(self,name,password):
            self.name = name
            self.password = password
            self.save()
    
    class Student(BaseClass):
        def __init__(self):
            self.name = ''
            self.password = ''
            self.school = ''
            self.course_list = []
        def choose_course(self,course_name):
            self.course_list.append(course_name)
            self.save()
    
    # 调用接口层的注册方法
    def register_interface(name,pwd):
        obj = Admin.get_obj_by_name(name)
        if not obj:
            admin = Admin()
            admin.register(name,pwd)
    
    #### 写在用户层
    name = input('name')
    password = input('password')
    
    register_interface(name,password)
    
    #### 接口层
    def choose_course_interface(student_name,course_name):
        # 取到学生对象
        student = Student.get_obj_by_name(student_name)
        student.choose_course(course_name)
    
    # 学生选课功能
    # 用户功能层
    # 假设课程全部打印出来了
    course_name = 'linux'
    student_name = 'bob'
    
    choose_course_interface(student_name,course_name)
    
    def check_all_student_course(student_name):
        student = Student.get_obj_by_name(student_name)
        return student.get_courses()
    
    # 查询学生选的所有课程
    check_all_student_course(student_name)
    
    
    # 继承查找顺序(新式类,经典类)
    # 广度优先和深度优先
    # 在子类中调用父类的方法
    # 指名道姓
    # super(类名,对象).父类的方法名()  super 严格按照mro列表查找
    # 派生
    # 多态和多态性
    # 控制子类必须实现父类的方法:abc模块,通过抛异常
    # 鸭子类型:不用父类强制约束,人为约束
    
    # 封装
    # 组合也属于封装
    # 隐藏属性和方法
    # 用__放在属性或者方法面前:能把属性和方法隐藏
    # 隐藏属性为了安全
    # 隐藏方法为了隔离复杂度
    # propertory:把方法包装成数据属性
    # 修改:@方法名.setter+6
    # 删除:@方法名.deleter
    
    # classmethod:类的绑定方法
    # staticmethod:静态方法(非绑定方法)
    
  • 相关阅读:
    StringTokenizer类的使用
    ResultSet相关ResultSetMetaData详细
    jdbcTemplate 获取数据表结构
    关于数组和List之间相互转换的方法
    cat ,more, Less区别
    落地数据和不落地数据
    eclipse代码格式化
    如何修改word的项目编号
    .Net配置文件——反射+配置文件存储类型实例
    unix mkdir命令的使用方法
  • 原文地址:https://www.cnblogs.com/yushan1/p/11432172.html
Copyright © 2011-2022 走看看