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

    面向对象基础

    继承

    如何使用继承

    ​ class 类名(父类1,父类2):

    ​ pass

    本质

    ​ 是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中

    父类/基类

    子类/派生类

    新式类

    ​ 只要继承了object类,就是新式类,在python3中,默认继承object类

    ​ python2中,需要显示的指定继承object

    经典类

    ​ 没有继承object的类,就是经典类

    ​ python3中没有经典类

    继承重用父类

    方法一:指名道姓(跟继承没有关系)

    class A:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.course = None
    
    class B(A):
        #没有自己的__init__,直接继承A的
        def create_course(self, course_name):
            self.course = course_name
    class C(A):
        #C有自己的__init__,需要声明A的__init__才能使用A的
        def __init__(self, name, age, gender):
            A.__init__(self, name, age): #指名道姓A使用它的__init__方法
                self.gender = gender #派生
                
            
    

    方法二:super关键字

    1. 严格以继承属性查找关系(.mro列表中的顺序)

    2. super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性(按照继承的关系)

    3. super的完整用法是super(自己的类名,self), python3中可以简写

    4. super.init()不用为self传值

    class A;
    	def __init__(self, name, age):
            self.name = name
            self.age = age
         def t(self)
        	print('这是A的t方法')
    class B(A):
        def __init__(self, name, age, sex):
            #super(B,self).(name, age)#完整的写法,在python2中会用到,python3中按下面的写
            super().__init__(name, age) # 直接继承了父类的两个属性,必须要写两个
            self.sex = sex
        def t(self):
            #A.t(self)#和下面的语句具有相同的意思
            super().t # 调用该方法打印出 这是A的t方法
    

    组合

    通俗来讲,我有一个黑色书包,那么我是人类的对象,黑色书包是书包类的对象,则“我有黑色书包这句话就是组合:即一个对象的属性是另一个对象”

    class Person:
        def __init__(self, bag):
            self.bag = bag
    
    class Bag:
        def __init__(self, pencil, pen):
            self.pencil = pencil
            self.pen = pen
    
    p = Person('nike')
    b = Bag('pencil', 'pen')
    p.b = b
    print(p.b.pencil) #pencil  相当于b对象
    print(p.b)#<__main__.Bag object at 0x0000017299CDD518>#打印b对象的内存地址
    print(p.bag)#打印书包的名称 nike
    
    

    多态和多态性

    多态: 一类事物的多种形态

    例如:动物类有猪,狗,人

    多态性: 不考虑实例类型的情况下使用实例,比如‘讲话’这个属性,可以有‘人讲话’、‘猪讲话’、‘狗讲话’

    注意python中崇尚鸭子类型:即不会强制执行,看起来、叫声、走路像鸭子就是鸭子,就是在每个派生类里面写相同名字的方法

    方式一:

    用abc实现接口统一化,约束代码(用的比较少)

    import abc
    #第一在括号中写metaclass=abc.ABCMeta
    class Animal(metaclass=abc.ABCMeta):
        #第二在要约束的方法上,写abc.abstractmethod装饰器
        @abc.abstractmethod
        def speak(self):
            pass
        
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    class Dog(Animak):
        def aa(self):
            print('旺旺旺')
    
    pig = Pig()
    pig.speak() #正常打印
    dog = Dog()     
    dog.aa()# 会报错
    

    方式二:

    用异常处理来实现(常用)

    class Animal():
        def speak(self):
            #主动抛出异常
            raise Exception('你得给我重写它啊')
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    class People(Animal):
        def speak(self):
            print('say hello')
    
    pe=People()
    pe.speak() # say hello
    
    
    class Animal():
        def speak(self):
            #主动抛出异常
            raise Exception('你得给我重写它啊')
    class Pig(Animal):
        def spk(self):
            print('哼哼哼')
    class People(Animal):
        def sak(self):
            print('say hello')
    
    pe=People()
    pe.speak() # Exception: 你得给我重写它啊
       
    

    方式三:

    最常用(约定俗成写一样的方法名)

    #都写speak方法
    class Pig:
        def speak(self):
            print('哼哼哼')
    class People:
        def speak(self):
            print('say hello')
    
    

    封装

    就是汉语封装,把所有东西装在一个容器内,隐藏起来

    1. 隐藏属性(为了安全)

    class Person:
        def __init__(self,name,age):
            self.__name=name #__变量名来隐藏
            self.__age=age
        def get_name(self):
            # print(self.__name)
            return '[----%s-----]'%self.__name
    
    p=Person('nick',89)
    print(p.age) #报错 AttributeError: 'Person' object has no attribute 'age'
    
    print(p._Person__name)# 可以访问 或者通过p.__dict__取出值
    

    2.隐藏方法(隔离复杂度)

    class Person:
        def __init__(self,name,age):
            self.__name=name
            self.__age=age
        def __speak(self):
            print('6666')
    p=Person('nick',89)
    p.__speak() #报错 AttributeError: 'Person' object has no attribute '__speak'
    print(Person.__dict__)
    p._Person__speak() # 用对象的字典可以拿出来
    

    property装饰器:把方法包装成数据属性

    #property装饰器:把方法包装成数据属性
    class Person:
        def __init__(self,name,height,weight):
            self.name=name
            self.height=height
            self.weight=weight
        @property
        def bmi(self):
            return self.weight/(self.height**2)
            # return self.weight/(self.height*self.height)
    p=Person('lqz',1.82,70)
    # # print(p.bmi())
    print(p.bmi) #bmi直接返回数值 21.132713440405748
    
    

    property之setter

    class Person:
        def __init__(self,name,height,weight):
            self.__name=name
            self.__height=height
            self.__weight=weight
        @property
        def name(self):
            return '[我的名字是:%s]'%self.__name
        #用property装饰的方法名.setter #可以限制属性的修改,规定标准
        @name.setter
        def name(self,new_name):
            # if not isinstance(new_name,str):
            if type(new_name) is not str:
                raise Exception('改不了')
            if new_name.startswith('sb'):
                raise Exception('不能以sb开头')
            self.__name=new_name
    
        # 用property装饰的方法名.deleter
        @name.deleter
        def name(self):
            # raise Exception('不能删')
            print('删除成功')
            # del self.__name
    
    p=Person('lqz',1.82,70)
    p.name=123
    print(p.name) #Exception: 改不了
    

    类的绑定方法

    绑定给类的,类来调,会把类自身传过去

    一般用在不需要通过对象,只需要通过类就能获得一些东西,可以由对象调用,但不建议

    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)
    per1=Person.test()
    print(per1) #打印的是: 类的绑定方法
    

    类的非绑定方法

    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() #我是静态方法,谁都不绑定
    
    

    静态方法(非绑定方法)的作用跟类和对象都没有关系的时候,可以定义成静态方法,一般在类内部使用,类外部也可以使用就是一个普通函数,想把它拿到类中管理,就可以定义成静态方法

    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()
        
    p=Person('nick',19)
    print(Person.get_uuid()) # 15ee76bf-930d-4297-87ba-036771e3e3de
    
  • 相关阅读:
    Java——HashSet和TreeSet的区别
    TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树
    Java 数组元素逆序Reverse的三种方式
    Java开发中使用sort排序
    Android Studio导入第三方库的三种方法
    Android下拉涮新第三方通用控件
    手把手教你MyEclipseUML建模(下)
    手把手教你MyEclipseUML建模(上)
    java enum(枚举)使用详解 + 总结
    翻译学python---《Learn Python the hard Way》---第一章 绪论
  • 原文地址:https://www.cnblogs.com/michealjy/p/11443989.html
Copyright © 2011-2022 走看看