Python进阶--面向对象

1、对象
  • 世间万物皆对象
  • 通常将对象划分为两部分,即静态部分(属性)和动态部分(行为)。
  • Python天生就是面向对象的
2、面向对象
  • 封装——将对象的属性和行为封装起来,为用户提供一下使用接口即可,载体是类。
  • 继承——实现重复利用的重要手段,子类通过继承复用了父类的属性和行为的同时,又添加了子类特有的属性和行为
  • 多态——将父类对象应用于子类的特征,子类继承父类特征的同时,也具备了自己的特征,能够实现不同的效果
3、类的定义和使用
  • 类表示具有相同属性和方法的对象的集合

  • 先定义类,再创建类的实例,通过类的实例访问类中的属性的方法

    (1)定义类
    class 类名:
    	类型
        
    (2)创建类的实例
    实例=类名(参数)
    
    (3)创建构造方法
    def __init__(self): 
    - 每当创建一个类的新实例时,Python会自动执行它
    - 方法的第一个参数必须是self参数,是一个指向实例本身的引用,用于访问类中的属性和方法,在方法调用时会自动传递实际参数self
    - 当方法只有一个参数时,在创建类的实例时,就不需要指定实际参数了
    - 首尾的英文双下划线旨在区分普通方法和默认方法
    
    (4)创建类的成员
    
    即定义类的方法与属性,使用类的实例去访问、使用
    
    (4.1)创建方法去访问
    def 方法名(self,其他参数):		#实例方法的第一个参数必须是self
    	方法体    
    - 函数实现的是某个独立的功能,而实例方法是实现类中的一个行为,是类的一部分
    
    实例名.方法名(参数)				#访问方法
    
    (4.2)创建属性去访问
    数据成员指在类中定义的变量,根据定义的位置,分为类属性和实例属性
    【类属性】——定义在类中,类方法体外,所有对象都可以使用,可以通过类名称或实例名去访问
    【实例属性】——定义在类方法中的属性,只能通过实例名去访问
    
    
    eg:   
    class Bird:
        leg="我的腿很长"
        num=0		#类属性在类的所有实例之间共享应用值	
        
        __ceshi1="私有属性"
        _ceshi2='保护属性'
        
        def __init__(self,wing):
            self.neck="我的脖子很长"		#实例属性
            num +=1
            print("我是一只可爱的小鸟")
        def sbird(self,state):            #实例方法的第一个参数必须是self参数
            print(state)
            print("我是通过类名访问的"+Bird.leg)					
            
            
    wing="我有一双翅膀,你有吗"
    state="我是一只漂亮的小鸟"
    bird=Bird(wing)				#我是一只可爱的小鸟    num=1
    print(bird)					#<__main__.Bird object at 0x000001FD9E14E8C0>  #在实例化时,虽然没有给为init方法指定参数,但是该方法会自动执行
    bird.sbird(state)			#我是一只漂亮的小鸟   #我是通过类名访问的我的腿很长
    print("我是通过实例名访问的"+Bird.leg)		#我是通过实例名访问的我的腿很长
    
    abird=Bird(wing)		#num=2
    
    print(bird.neck)			#只能通过实例名去访问   #我的脖子很长
    
    
    print(bird._Bird__ceshi1)       #通过实例名访问私有属性
    print(bird._ceshi2)             #通过实例名访问保护属性
    
  • 访问限制

    • 类的内部可以定义属性和方法,类的外部可直接访问
    • Python默认没有限制,但是,我们可以添加限制
      • _单下划线 ——protect(保护)类型,访问方式:类本身<类实例>,子类
      • __双下划线 ——private(私有)类型,访问方式:类本身<类实例>,类的实例名.-类名-xxx
      • --首尾双下划线-- ——特殊方法,系统定义的名字
4、属性
  • 不是指类属性和实例属性,是计算属性,将一块儿计算的代码(方法,有return),转换为一个属性

  • 介绍一种特殊的属性,访问它时将计算它的值,该属性还可以为属性添加安全保护机制

  • 实现方式:

    • @property ——装饰器
    • 将一个方法转换为属性,从而用于实现计算的属性
    • 将方法转换为属性后,可以直接通过方法名来访问
    • 装饰器转换后的属性不能重新赋值
  • 为属性添加安全保护机制

    • Python默认的情况下,创建的类属性或者实例可以在类体外进行修改

    • @property实现只读属性,即让它在类体外可以读取,但不能修改

    • 可以为属性设置拦截器,允许对属性进行修改,但需要遵守一定的约定

    @property
    def 方法名():
    	方法体
           
    eg:
    class Bird():
        i=7
        def __init__(self,show,width,height):
            self.__show=show     #定义一个私有属性
            self.width=width
            self.height=height    
    
        #通过装饰器,使得私有属性在类外只读
        @property
        def show(self):
            return self.__show     #调用私有属性
        
        
        
        #设置setter方法,让属性可修改
        @show.setter
        def show(self,value):
            self.__show=value
    
    
        @property
        def score(self):
            return self.width*self.height   
            
            h=4          
            return h
            
            return Bird.i
    
            return 5
    
    
    tv=Bird("鸟人",3,4)
    print(tv.show)		#鸟人
    
    tv.show='大树'
    print(tv.show)		#大树
    
    print(tv.score)		#12,4,7,5
    
5、继承
  • 表示这个类拥有它继承的类的所有公有成员或者受保护成员

  • 被继承的叫做父类或基类,新的类称为子类或派生类

  • python和c++支持多继承,java支持单继承

  • 重写

  • 子类定义init方法时,不会自动调用父类的init方法。要让子类调用父类init方法,必须进行初始化,需要在子类中使用super函数

    class 子类名(父类名):
    	类体
            
    eg:
        
    class Fruit:
    
        def __init__(self,color="绿色"):
            Fruit.color=color
            print('我是父类的init')
        
        def harvest(self,color):
            print("我是父类,水果是"+color)
    
    class Apple(Fruit):
        color="红色"
        def __init__(self,color):
            print("我是子类-苹果")
           # super().__init__(color)          #调用基类的init方法
        '''
        如果不调用super
        main中添加
        fruit=Fruit()
        结果是:
    	我是子类重写父类方法,苹果是红色
    	没有重写的时候,苹果是绿色
        '''
        
    
        def harvest(self,color):
            print("我是子类重写父类方法,苹果是"+color)  #形参
            print("没有重写的时候,苹果是"+Fruit.color)  #类属性
        
    
    
    apple=Apple("粉色")       #我是子类—苹果   我是父类的init
    apple.harvest(apple.color)   #apple虽然没有harvesr方法,但python允许子类访问父类的方法  
    
    我是子类重写父类方法,苹果是红色
    没有重写的时候,苹果是粉色
    
    emo~

图跑了