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
    
  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/biechishaobing/p/10934046.html
Copyright © 2011-2022 走看看