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

    # 面向对象
    """
    面向对象特点
    1.封装: 依据功能需求将某些属性与方法封装到一个类中
    2.继承: 实现代码的重复调用,相同的功能调用不需要重复编写
    3.多态: 不同的对象调用相同的类方法,产生不同的执行结果
    
    面向对象的基本知识点
    类: 描述具有相同的属性和方法的对象的集合,具有抽象性,不能直接使用,主要职责是创建对象
    对象:通过类定义的,具有属性与方法的具体实例,可以使用
    方法:类中定义的函数
    类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用
    数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
    方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    局部变量:定义在方法中的变量,只作用于当前实例的类。
    实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
    继承:即一个派生类(derived class)继承基类(base class)的字段和方法。
    实例化:创建一个类的实例,类的具体对象。
    在程序开发中,应该 先有类,再有对象
    类和对象的关系: 类是模板,对象是根据类这个模板创建出来的  类只有一个,而对象可以有很多个
                   类中定义了什么属性和方法,对象中就有什么属性和方法,不可能多,也不可能少
    
    """
    
    # 类的设计
    """
    类名 这类事物的名字,满足大驼峰命名法(每一个单词的首字母大写,单词与单词之间没有下划线)   
    属性 这类事物具有什么样的特征(对象的特征描述)
    方法 这类事物具有什么样的行为(对象具有的行为)
    """
    # 定义简单的类 只包含方法
    """
    class 类名:
        def 方法1(self, 参数列表):
            pass 
        def 方法2(self, 参数列表):
            pass
    对象变量 = 类名()        
    类中定义方法第一个参数必须是self
    在类封装的方法内部,self 就表示当前调用方法的对象自己
    调用方法时,程序员不需要传递 self 参数
    在方法内部 可以通过 self. 访问对象的属性  也可以通过 self. 调用其他的对象方法
    """
    class P1:
        def say(self):
            print('你好')
    
    a = P1()
    a.say()
    
    # 类的初始化
    """
    当使用 类名() 创建对象时,会 自动 执行以下操作:
        为对象在内存中 分配空间 —— 创建对象
        为对象的属性 设置初始值 —— 初始化方法(__init__ )
    """
    # 通过初始化方法在类的内部设置属性
    class P2:
        def __init__(self):
            self.name = '小明'
        def say(self):
            print("你好%s" % self.name)
    b = P2();
    b.say()
    
    # 通过初始化方法传参在类的内部设置属性
    class P3:
        def __init__(self, name):
            self.name = name
        def say(self):
            print("你好%s" % self.name)
    c = P3('小李');
    c.say()
    
    # 内置方法 __del__
    """
    当使用类名()创建对象时,为对象分配完空间后,自动调用 __init__ 方法
    当一个 对象被从内存中销毁前,会自动调用 __del__ 方法
    生命周期:
        一个对象从调用类名()创建,生命周期开始
        一个对象的__del__方法一旦被调用,生命周期结束
        在对象的生命周期内,可以访问对象属性,或者让对象调用方法
    """
    class P4:
        def __init__(self):
            print('生命开始')
        def __del__(self):
            print('生命结束')
    d = P4()
    del d
    
    # 内置方法 __str__
    """
    使用 print 输出 对象变量,默认情况下,会输出这个变量 引用的对象 是 由哪一个类创建的对象,以及 在内存中的地址(十六进制表示)
    如果在开发中,希望使用 print 输出 对象变量时,能够打印 自定义的内容,就可以利用 __str__ 这个内置方法了
    """
    class P5:
        def __init__(self):
            print("生命开始")
        def __del__(self):
            print("生命结束")
        def __str__(self):
            return "我是一个类"
    
    e = P5()
    print(e)
    
    # 私有属性和私有方法
    """
    在实际开发中,对象的某些属性或方法可能只希望在对象的内部被使用,而不希望在外部被访问到
    私有属性 就是对象不希望公开的属性
    私有方法 就是对象不希望公开的方法
    在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
    并没有真正意义的私有  在名称 前面加上 _类名 => _类名__名称 可以访问到类的私有属性和方法
    """
    class P6:
        def __init__(self):
            self.__age = 25
        def __mimi(self):
            print('秘密')
        def say(self):
            print("年龄是" % self.__age)
    f = P6()
    # print(f.__age)  # 类的外部不能调用私有属性
    # f.__mimi()  # 类的外部不能调用私有方法
    print(f._P6__age)
    f._P6__mimi()
    
    # 类的继承
    """
    类的单继承
    子类拥有父类的所有方法和属性
    class 类名(父类名):
        pass
    子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
    子类中应该根据 职责,封装子类特有的属性和方法
    
    继承的传递性
    C类从B类继承,B类又从A类继承
    那么C类就具有B类和A类的所有属性和方法
    子类拥有父类以及父类的父类中封装的所有属性和方法
    
    继承中的方法重写
    当父类的方法实现不能满足子类需求时,可以对方法进行 重写(override)
    重写 父类方法有两种情况:
    1. 覆盖父类的方法: 如果在开发中,父类的方法实现和子类的方法实现,完全不同,就可以使用 覆盖 的方式,在子类中 重新编写 父类的方法实现
                      具体的实现方式,就相当于在 子类中 定义了一个 和父类同名的方法并且实现
    2.对父类方法进行扩展  如果父类原本封装的方法实现是子类方法的一部分
         在子类中重写父类的方法
         在需要的位置使用super().父类方法 来调用父类方法的执行
         代码其他的位置针对子类的需求,编写子类特有的代码实现
            
    父类的私有属性和私有方法
        子类对象 不能 在自己的方法内部,直接 访问 父类的 私有属性 或 私有方法
        子类对象 可以通过 父类 的 公有方法 间接 访问到 私有属性 或 私有方法
    """
    class Person:
        def __init__(self, name):
            self.name = name
            self.__age = 25
        def __mimi(self):
            print('这是一个秘密')
    
        def mimi(self):
            print('这是一个秘密')
        def say(self):
            print("你好%s" % self.name)
        def eating(self):
            print('我最爱吃')
    
    class Student(Person):
        def run(self):
            print(self.name)
            # print(self.__age)  # 子类不能调用父类的私有属性
            self.mimi()
            # self.__mimi()      # 子类不能调用父类的私有方法
            print('我跑的快')
        def say(self):
            print('我是小学生')
        def eating(self):
            super().eating()
            print('%s也一样爱吃' % self.name)
    class Stu(Student):
        def __str__(self):
            return '我爱python'
    
    aa = Student('小明')
    aa.say()
    aa.run()
    aa.eating()
    bb = Stu('张飞')
    bb.say()
    bb.eating()
    
    # 多继承
    """
    类可以拥有多个父类,并且具有所有父类的属性和方法
    
    class 子类名(父类名1, 父类名2...)
        pass
    
    如果不同的父类中存在同名的方法  依据继承顺序执行 当前类、继承第一个类、第二个类...
    内置属性 __mro__ 用于在多继承时判断方法、属性的调用路径 查看 方法 搜索顺序
    
    """
    class O1:
        def test(self):
            print('test...')
    class O2:
        def demo(self):
            print('demo...')
        def test(self):
            print('...test....')
    class O3(O1, O2):
        def say(self):
            print('say')
    class O4(O2, O1):
        def say(self):
            print('say')
    
    gg = O3()
    gg.test()
    gg.demo()
    gg.say()
    jj = O4()
    jj.test()
    
    # 多态 不同的子类对象 调用相同的父类方法,产生不同的执行结果
    class Dog(object):
        def __init__(self, name):
            self.name = name
        def game(self):
            print("%s 蹦蹦跳跳的玩耍..." % self.name)
    
    class XiaoTianDog(Dog):
        def game(self):
            print("%s 飞到天上去玩耍..." % self.name)
    
    class Person(object):
        def __init__(self, name):
            self.name = name
    
        def game_with_dog(self, dog):
            print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name))
    
            # 让狗玩耍
            dog.game()
    
    # 1. 创建一个狗对象
    # wangcai = Dog("旺财")
    wangcai = XiaoTianDog("飞天旺财")
    
    # 2. 创建一个小明对象
    xiaoming = Person("小明")
    
    # 3. 让小明调用和狗玩的方法
    xiaoming.game_with_dog(wangcai)
    
    # 类属性和类方法
    """
    封装实例的属性和方法外,类对象还可以拥有自己的属性和方法
    通过类名. 的方式可以访问类的属性或者调用类的方法
    类属性 就是给类对象中定义的属性
    通常用来记录与这个类相关的特征
    类属性不会用于记录具体对象的特征
    属性的获取机制: 首先在对象内部查找对象属性、没有找到的情况下向上寻找类的属性
    如果使用 对象.类属性 = 值 赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值
    """
    
    # 定义类属性
    class P8:
        count = 0  # 类属性
        def __init__(self, name):
            self.name = name
    k = P8('小呢咋')
    print(k.count)  # 不推荐
    print(P8.count)  # 推荐
    
    # 类方法和静态方法
    """
     类方法 就是针对 类对象 定义的方法
     在类方法内部可以直接访问类属性或者调用其他的类方法
     
     类方法需要用 修饰器 @classmethod 来标识,告诉解释器这是一个类方法
     类方法的 第一个参数 应该是 cls
     可以通过cls.访问类的属性
     也可以通过cls.调用其他的类方法  不是对象方法
     @classmethod
     def 类方法名(cls):
        pass
    
    """
    class P10:
        count = 0
        def __init__(self, name):
            self.name = name
        def say(self):
            print('你好')
    
        @classmethod
        def test(cls):
            print('哈哈')
        @classmethod
        def show(cls):
            print(cls.count)
            cls.test()
    mn = P10
    P10.show()
    
    # 静态方法
    """
    静态方法
        既不需要访问实例属性或者调用实例方法
        也不需要访问类属性或者调用类方法
    
    静态方法 需要用 修饰器 @staticmethod 来标识,告诉解释器这是一个静态方法
    @staticmethod
    def 静态方法名():
        pass
        
    通过类名.调用静态方法
    """
    class P20:
        count = 0
        def __init__(self, name):
            self.name = name
        @staticmethod
        def run():
            print('快跑')
    
    P20.run()
    
    # 单例
    """
    目的是让类创建的对象,在系统中只有唯一的一个实例
    每一次执行类名()返回的对象,内存地址是相同的
    __new__ 方法
      1) 在内存中为对象分配空间
      2) 返回对象的引用
    Python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__ 方法
    Python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__ 方法
    __new__ 是一个静态方法,在调用时需要主动传递cls参数
    """
    
    # 示例
    class MusicPlayer(object):
        def __new__(cls, *args, **kwargs):
            return super().__new__(cls)
    
        def __init__(self):
            print("初始化音乐播放对象")
    
    player = MusicPlayer()
    print(player)
    
    # Python 中的单例
    """
    定义一个类属性,初始值是None,用于记录单例对象的引用
    重写__new__ 方法
    如果类属性is None,调用父类方法分配空间,并在类属性中记录结果
    返回类属性中记录的对象引用
    """
    class MusicPlayer(object):
        # 定义类属性记录单例对象引用
        instance = None
        def __new__(cls, *args, **kwargs):
            # 1. 判断类属性是否已经被赋值
            if cls.instance is None:
                cls.instance = super().__new__(cls)
    
            # 2. 返回类属性的单例引用
            return cls.instance
    
    # __init__ 对象初始化只被执行一次
    """
    定义一个类属性 init_flag 标记是否 执行过初始化动作,初始值为 False
    在 __init__ 方法中,判断 init_flag,如果为 False 就执行初始化动作
    然后将 init_flag 设置为 True
    这样,再次 自动 调用 __init__ 方法时,初始化动作就不会被再次执行 了
    """
    class MusicPlayer(object):
        # 记录第一个被创建对象的引用
        instance = None
        # 记录是否执行过初始化动作
        init_flag = False
    
        def __new__(cls, *args, **kwargs):
            # 1. 判断类属性是否是空对象
            if cls.instance is None:
                # 2. 调用父类的方法,为第一个对象分配空间
                cls.instance = super().__new__(cls)
    
            # 3. 返回类属性保存的对象引用
            return cls.instance
    
        def __init__(self):
            if not MusicPlayer.init_flag:
                print("初始化音乐播放器")
    
                MusicPlayer.init_flag = True
    
    
    # 创建多个对象
    player1 = MusicPlayer()
    print(player1)
    
    player2 = MusicPlayer()
    print(player2)
    
    # 新式类
    """
    object 是 Python 为所有对象提供的 基类,提供有一些内置的属性和方法
    新式类:以 object 为基类的类,推荐使用
    经典类:不以 object 为基类的类,不推荐使用
    在 Python 3.x 中定义类时,如果没有指定父类,会 默认使用 object 作为该类的 基类
    为了保证编写的代码能够同时在 Python 2.x 和 Python 3.x 运行  如果没有父类,建议统一继承自 object
    class 类名(object):
        pass
    """

    面向对象

  • 相关阅读:
    主键索引就是聚集索引吗?
    聚集索引以及非聚集索引
    IO阻塞模型、IO非阻塞模型、多路复用IO模型
    Log4j的使用说明
    前置机是什么
    转:图文理解区块链
    DQL、DML、DDL、DCL全名是啥?
    OLAP和OLTP的区别
    JAVA之运算符优先级
    JAVA之异常处理(一)
  • 原文地址:https://www.cnblogs.com/ddf128/p/12014489.html
Copyright © 2011-2022 走看看