• (八)面向对象基础(二)


    类的三大特性:封装、继承、多态
        封装:根据职责将属性和方法封装到一个抽象的 类 中
        继承:子类可以直接使用父类的方法和属性(父类不能使用子类的功能)
     单继承:子类只继承一个父类
    # 父类class A(object):
    pass
    
    # 子类class B(A):
    pass
    • 子类在继承的时候,在定义类时,小括号()中为父类的名字
    • 父类的属性、方法,会被继承给子类
    • 父类的私有属性,子类不会继承,不能直接使用
    • {is a:代表了继承关系,is前是子类;has a:代表了属性关系,a后面是属性}
    多继承:子类继承多个父类
    # 父类class A(object):
    pass
    # 父类class B(object):
    pass
    
    # 子类class C(A,B):   子类继承多个父类
    • 多继承可以继承多个父类,也继承了所有父类的属性和方法
    • 注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)
    • 多个父类中,不重名的属性和方法,不会有任何影响。
    附:MRO算法:确定了查找父类方法的顺序
     
    强制指定父类功能:父类名.父类方法(子类对象)
     
    重写:父类和子类都由同名方法,子类调用的是自己的方法
         重写之后 发现父类方法仍然有执行的必要,可以强调调用父类方法
    ①:父类名.父类方法(self)
    ②:super(子类名,self).父类方法()
    # super(子类名, self).__init__() # 执行父类的 __init__方法
    ③:super().父类方法()  附:python2不能使用
     
    关于super().__init__()代码的说明
    这一行代码,可以调用也可以不调用,建议调用,因为__init__方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的__init__方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中,如果重写了父类的__init__方法,最好是先调用父类的这个方法,然后再添加自己的功能
    :无论何时何地,self都表示是子类的对象。在调用父类方法时,通过传递self参数,来控制方法和属性的访问修改。
     
    多态:父类能工作的地方子类就能工作,并且不同子类会产生不同的执行效果
        作用:在保证代码稳定性的情况下,提高了调用的灵活性
        多态以 继承 和 重写 父类方法 为前提
        实现:1.定义父类,提供公共方法
                   2.定义子类,重写方法
                   3.调用方法,传递不同的子类,可以产生不同的执行效果
     

    私有权限:在属性名和方法名 前面 加上两个下划线 __

    1. 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
    2. 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
    3. 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。
     
    对象分类:类对象、实例对象
        类对象:遇到class  python解释器会自动创建
        实例对象:一个类只有一个类对象,但是可以有多个实例对象,由类创建
    方法分类:类方法、实例方法
        类方法:在方法上写一个装饰器@classmethod声明;方法的第一个形参必定是调用方法的类对象,一般以cls表示。
    • 类方法一般和类属性配合使用,用于访问和修改类属性
    class Dog(object):
    __type = ""
    
    def get_type(cls): # 类方法,用classmethod来进行修饰 @classmethod
    return cls.__type
    print(Dog.get_type())
        静态方法在方法上写一个装饰器@staticmethod声明;静态方法及不需要传递类对象也不需要传递实例对象(形参没有self/cls)

            使用场景:

    • 当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
    • 取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗
    class Dog(object):
    type = ""
    def __init__(self):
    name = None
    @staticmethod # 静态方法
    def introduce(): # 静态方法不会自动传递实例对象和类对象
    print("犬科哺乳动物,属于食肉目..")
    
    dog1 = Dog()
    Dog.introduce() # 可以用 实例对象 来调用 静态方法
    dog1.introduce() # 可以用 类对象 来调用 静态方法
    • 调用类方法:类名.类方法()        调用静态方法:类名.类方法()
    • cls:一般代表类对象        
        实例方法:接受实例对象的方法,实例方法是所有对象共享的
     
    属性分类:类属性、实例属性
        实例属性:每一个实例对象的属性,彼此间是独立的,互不干扰
            在类内部获取 属性 ,通过self获取
            在类外部获取 属性 ,通过对象名获取
        类属性:类对象的属性,在整个类里只有一个,由所有实例对象共享
            使用类属性:类名.类属性
            类属性只能通过类对象修改,不能通过实例对象修改,实例对象修改类属性,实际上添加了一个新的实例属性
     
     
    单例模式
        控制一个类最多只能生成一个对象的设计模式
    # 实例化一个单例class Singleton(object):
    __instance = None
    
    def __new__(cls, age, name):
    #如果类属性__instance的值为None,
    #那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时
    #能够知道之前已经创建过对象了,这样就保证了只有1个对象
    if not cls.__instance:
    cls.__instance = object.__new__(cls)
    return cls.__instance
    
    a = Singleton(18, "dongGe")
    b = Singleton(8, "dongGe")
    
    print(id(a))
    print(id(b))
    
    a.age = 19 #给a指向的对象添加一个属性
    print(b.age)#获取b指向的对象的age属性
     
     
  • 相关阅读:
    A4纸网页打印 html网页页面的宽度设置成多少
    怎样使用 css 的@media print控制打印
    jquery 表格自动拆分(方便打印)插件-printTable
    【转】编写高质量代码改善C#程序的157个建议——建议107:区分静态类和单例
    【转】编写高质量代码改善C#程序的157个建议——建议106:为静态类添加静态构造函数
    【转】编写高质量代码改善C#程序的157个建议——建议104:用多态代替条件语句
    【转】编写高质量代码改善C#程序的157个建议——建议103:区分组合和继承的应用场合
    【转】编写高质量代码改善C#程序的157个建议——建议102:区分接口和抽象类的应用场合
    【转】编写高质量代码改善C#程序的157个建议——建议101:使用扩展方法,向现有类型“添加”方法
    【转】编写高质量代码改善C#程序的157个建议——建议100:静态方法和实例方法没有区别
  • 原文地址:https://www.cnblogs.com/qingchang/p/8976548.html
Copyright © 2020-2023  润新知