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

    新式类与旧式类

    区别:

    1. 在2.2版本之前所有的类都是旧式类,3.x版本已取消旧式类
    2. 旧式类一般的写法,不继承任何父类
    class Person:
        def __init__(self, name):
            self.name = name
    
    1. 在旧式类中,子类不能通过super函数来调用父类的函数
    class Student(Person):
        def __init__(self, name):
            print('初始化Student类')
            # 如果在2.x版本中运行以下函数执行的时候将会报错,3.x版本中已取消旧式类,使用以下方法可以正常执行
            # super(Student, self).__init__(name)
            # 在旧式类中需要通过以下形式来调用父类中的参数
            # Person.__init__(self,name)
    
    print(type(s1))  # 如果为新式类该方法则输出Student,如果为旧式类该方法则输出instance
    

    继承

    重写父类方法

    class Person(object):  # 父类
        
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print('人在吃饭')
    
        def greet(self):
            print('你好,我是%s,我今年%d岁了!' % (self.name, self.age))
    
    
    class Student(Person):  # 子类
    
        def __init__(self, name, age):
            super(Student, self).__init__(name, age)
            print('初始化一个学生')
    
        def eat(self):  # 重写eat方法
            print('学生在吃饭')    
    
    
    p = Student('tangwenjie', 18)
    p.greet()   
    p.eat()     # 输出:学生在吃饭   执行顺序:当前类>父类
    

    私有属性与方法

    子类无法继承父类的私有方法与属性(变量或方法名前有两个下划线的方法或属性),但可以继承父类受保护的方法与属性(变量或方法名前有一个下划线的方法或属性)

    class Person(object):
    
        def __init__(self, name):
            self.__name = name
    
        def __greet(self):
            print('你好,我叫%s' % self.__name)
    
    
    class Student(Person):
    
        def greet(self):
            self.__greet()
    
        def eat(self):
            print(self.__name + '在吃饭')
    
    
    s1 = Student('ywj')
    s1.greet()  # 报错'Student' object has no attribute '_Student__greet'
    s1.eat()  # 报错'Student' object has no attribute '_Student__name'
    

    多继承

    1. 多继承的情况下天然拥有多个父类的方法
    2. 如果当前类与多个父类存在相同的方法时,执行的优先级是当前类的方法>位置靠前的父类的方法,具体顺序可通过类名.__mro__方法查询,且通过super的方式的执行顺序也是这样的
    3. 如果要指定执行某一个父类中的方法可以在当前类中通过指定父类.func(self)的方式实现
    class Ma(object):
        def run(self):
            print('马在奔跑')
    
        def eat(self):
            print('马在吃草')    
    
    
    class Lv(object):
        def lamo(self):
            print('驴在拉磨')
    
        def eat(self):
            print('驴在吃麦秆')    
    
    
    class Luozi(Lv, Ma):
        # def eat(self):
        #     print('骡子在吃稻谷')
        pass
    
    lz = Luozi()
    # 多继承的情况下天然拥有多个父类的方法
    # lz.run()
    # lz.lamo()
    # 如果当前类与多个父类存在相同的方法时,执行的优先级是当前类的方法>位置靠前的父类的方法,具体顺序可通过如下方法查询,且通过super的方式的执行顺序也是这样的
    # print(Luozi.__mro__)
    # 如果要指定执行某一个父类中的方法可以在当前类中通过Lv.eat(self)的方式实现
    # lz.eat()
    

    多态

    强类型语言:在声明一个变量时需要指定其类型,例如java、c++
    弱类型语言:即不需要在指定一个变量时指定其类型,例如python

    class Hero(object):
        def __init__(self):
            pass
    
        def stroke(self):
            pass
    
    class Chengyaojin(Hero):
        def stroke(self):
            print('程咬金的大招')
    
    
    class Xiangyu(Hero):
        def stroke(self):
            print('项羽的大招')
    
    h = input('请输入你想选择的英雄')        
    hero = None
    
    if h == '1':
        hero = Chengyaojin()
    else:
        hero = Xiangyu()
    
    hero.stroke()
    

    类属性和实例属性

    实例属性:绑定到对象上的属性,只能在当前对象上使用
    类属性:

    1. 可以通过实例进行访问,也可以直接通过类进行访问
    2. 如果通过实例修改类属性,实际上并没有真正修改类属性,而是在这个实例上面重新定义了一个名字相同的实例属性
    3. 要正确修改类属性只能通过类名.属性的方式来进行修改
    class Person(object):
        country = 'china' # 类属性
        def __init__(self, name):
            self.name = name # 实例属性
    

    类方法和实例方法

    实例方法:只能通过实例.func()进行调用,需要传递self(当前实例)参数
    类方法:可以通过类名.func()实例.func()进行调用,需要传递cls(当前类)参数
    静态方法:可以通过类名.func()实例.func()进行调用,不需要传递参数

    class Person(object):
        
        def eat(self): # 实例方法,传递当前实例
            print('实例方法')
    
        @classmethod
        def greet(cls): # 类方法,传递当前类
            print('类方法')    
    
        @staticmethod # 静态方法,不需要传递任何参数
        def static_method():
            print('静态方法')
    

    __new__方法

    1. 一个实例被新建时会首先执行这个类的__new__方法来创建这个实例,再调用__init__方法初始化个对象的属性
    2. __new__方法接收当前类与其他任意参数并返回被创建的这个对象
    3. 所以如果在定义类的时候重写了__new__方法,则必须要在这个方法最后返回当前这个类的对象
    class Car(object):
        def __new__(cls, *args, **kwargs):
            print('new method')
            return super(Car, cls).__new__(cls, *args, **kwargs)
        
        def __init__(self):
            print('car init method')
    
    car = Car()  # 输出:new method
    print(car)  # 输出:car init method
    

    单例设计模式

    单例:某个类或者模型在整个程序运行期间最多只能有一个对象被创建
    使用场景:比如一个项目中有一个配置文件,那么可以通过定义一个Config的类来操作配置信息,但是配置信息在整个项目中其实只需要一份就够了,这时候就可以使用到单例模式了。
    实现方法:该方式实现单例在多线程的情况下并不安全

    class User(object):
    
        # 1. 定义一个类属性默认值为None
        __instance = None                                      
    
        # 2. 重写__new__方法
        def __new__(cls, *args, **kwargs):   
            # 3.在创建实例前判断当前类中是否已经存在实例,如果不存在则创建实例                  
            if not cls.__instance:                        
                cls.__instance = super(User, cls).__new__(cls) 
            # 5.如果存在,则返回当前实例
            return cls.__instance                              
    
        def __init__(self, name):
            self.name = name
    
  • 相关阅读:
    当算法提升到哲学层面—小议验证码识别
    2014总结
    [脚本无敌2]python获取cocos 2dx项目文件列表
    单幅图构建三维图
    [思考]画个圈圈诅咒你
    Mybatis2
    Mybatis1
    淘淘商城虚拟机启动命令
    Zookeeper集群搭建zookeeper01启动不成功解决方案
    Mybatis的xml文件的相关配置
  • 原文地址:https://www.cnblogs.com/biechishaobing/p/10934046.html
Copyright © 2011-2022 走看看