面向对象

本文介绍了面向对象编程的基本概念,包括封装、继承、多态等核心特性,并通过Python语言进行了具体说明。

面向对象

特点:封装、继承、多态

  • python 一切皆对象
  • 所有的数据类型都是一个类
  • 所有的类型值都是一个具体的对象

自定义类

  • 回想函数

      def func():
          pass
  • 类的定义

      class 类名:
          def __init__(self, *args, *kwargs):
              属性 = 'a'
    
          def 
      #属性的调用
      类名.属性

类属性的补充

    一:我们定义的类的属性到底存到哪里了?有两种方式查看
    dir(类名):查出的是一个名字列表
    类名.__dict__:查出的是一个字典,key为属性名,value为属性值
    
    二:特殊的类属性
    类名.__name__# 类的名字(字符串)
    类名.__doc__# 类的文档字符串
    类名.__base__# 类的第一个父类(在讲继承时会讲)
    类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__# 类的字典属性
    类名.__module__# 类定义所在的模块
    类名.__class__# 实例对应的类(仅新式类中)
    
    类属性的补充  
    

对象的功能

  • 调用属性
  • 调用方法

类名的功能

类的组合

1. 继承性

  • 父类(基类、超类)
  • 子类(派生类)
  • 继承是创建新类的方式,一个类可以继承一个或多个父类

      class A:pass
      class B:pass
      class A_son(A):pass
      class AB_son(A, B):pass
  • .__bases__查看子类继承的父类

      print(A_son.__bases__)
      #结果
      (<class '__main__.A'>,) 
    
      #所有类的基类 -新式类
      print(A.__bases__)
      #结果
      (<class 'object'>,) #object类的最顶端的类
    • python3中没有没有父类的类
  • 小练习

      #狗类 吃 喝 看门
      #鸟类  吃 喝 下蛋
    
      #动物类
      class Animal:
          def eating(self):
              print('我正在吃')
    
          def drink(self):
              print('我正在喝水')
    
      #狗类
      class Dog(Animal):
          def kan_men(self):
              print('我能看门')
    
      #鸟类
      class Brid(Animal):
          def xia_dan(self):
              print('我能下蛋')
    
      #实例化狗
      xiao_hei = Dog()
      #实例化鸟
      tuo_niao = Brid()
    
      xiao_hei.drink()
      xiao_hei.eating()
      xiao_hei.kan_men()
    
      tuo_niao.drink()
      tuo_niao.eating()
      tuo_niao.xia_dan()  
      #结果
      我正在喝水
      我正在吃
      我能看门
      我正在喝水
      我正在吃
      我能下蛋
  • 子类中的方法会覆盖父类中的方法
  • 子类中和父类具有相同方法时又想调用父类的方法
  • 继承和派生

    单继承

    • 派生属性

        #创建一个父类,具有name属性
        class Father:
            def __init__(self, name):
                self.name = name
      
        #创建一个子类,具有name和age属性
        class Chrld(Father):
            def __init__(self, age):
                Father.__init__(self, name) #继承父类的属性                
                self.age = age  #派生子类特有的属性
    • 派生方法
      • 父类没有的方法子类有的方法叫派生方法
      • 如果父类里有子类的方法,子类的方法会覆盖父类的方法
  • super()关键字继承
    • super可以在类的外部使用,调用父类的方法
      • super(Chidren, Chidrend的实例).父类方法名(*args, *kwargs)
    • super(类名, self).方法名(*args, *kwargs)
    • 等同于类名.方法名(self, *args, *kwargs)
    • super()遵循广度优先继承

        class Animal:
            def __init__(self, name):
                self.name = name
      
        class Dog(Animal):
            def __init__(self, age)
                super().__init__(name)  #继承父类的__init__方法,
                #相当于Animal.__init__(self, name),
                #这个方法的全写是super(Animal, self).__init__(name)
                self.age = age
  • 类的继承和抽象
    • 抽象即类似比较像的
    • 继承是抽象的结果
    • 继承是类和类的关系

多继承

  • 新式类继承遵循广度优先继承
    • 钻石继承
    • 漏斗继承
    • 小乌龟继承
  • 经典类是深度优先继承
    • 经典类指python2.x
  • pthon3均是新式类

接口类和抽象类

  • 接口类和抽象类都是对面向对象开发的规范

接口类

  • 继承接口类必须具有接口类中被装饰的函数

      #定义一个接口类(规范类函数)
      from abc import absrtactmethod, ABCMeta
      class Jie_Kou(metaclass=ABCMeta)    #加上一个参数
          @abstractmethod #装饰器
          def func1(self):
              pass
    
          @abstractmethod #装饰器
          def func2(self):
              pass
  • 接口隔离原则
    • 使用多个单一的接口,而不使用一个总接口。即客户端不应该依赖的那些不需要的接口

抽象类

  • 抽象类也是一种规范
  • 一般是单继承
  • 子类继承的父类功能一致
  • 多继承的情况由于功能比较复杂,所以不容易抽象出相同功能的类

2. 多态性

  • 一个事物有多种形态
  • 一个类有多种形态
  • python语言是动态强类型语言
  • 鸭子类型
    • 不崇尚根据继承所带来的相似
    • 我只是自己实现我自己的代码就可以了
    • 如果两个类恰好相似并不产生兄弟关系,而是鸭子类型

3. 封装性

  • 将变量和函数都放进一个类中

封装的私有方法和私有属性

  • 利用双下划线来定义私有属性和方法
  • 所有的私有变量和私有方法是人为不想让你在类的外部使用,不是不能调取而是不想让你调取

      class Person():
          def __init__(self, name, age):
              self.name = name
              self.__age = age    #私有属性,只能内部调,外部不能调取
    
          def func1(self):    #用公有方法调用私有属性
              print(name)
              print(__age)    #在类的内部,正常调用
    
          def __func2(self):  #私有方法,只能内部调用
              pass
    
      #实例化对象
      alex = Person()
      alex.name
      alex.__age  #报错,找不到这个属性
      alex._Person__age   #正常调用,调用类中私有属性__age
    
      alex.func1()
      alex.__func2()  #报错,找不到这个方法
      alex._Person__func2()   #正常调用
  • 保护属性,不想让外界直接更改

      class Protect():
          def __init__(self, name)
              self.__name = name  #将属性name私有化
    
          def get_name(): #获取__name的值
              return self.__name
    
          def set_name(newName):  #更改__name的值
              self.__name = newName
              return self.__name
  • 保护属性不想让子类继承

          class Father():
              def __init__(self, name):
                  self.__name = name
    
          class   Child(Father):
              def __init__(self, age):
                  super.__init__(name)    #这一步会报错,父类的私有属性子类无法调用
          child = Child() #报错,无法找到_Child__name

封装里的内置函数

@property将函数伪装成属性

@私有变量名.setter设置私有变量的值

@私有变量名.deleter使用del关键字调用修饰的方法

from math import pi

#定义一个圆类 
class   Circle():       
    def __init__(self, r)
        self.r = r
        
    #圆面积
    @property
    def area(self):
        return self.r**2*pi
    
    @property       
    #圆周长
    def perimeter(self):
        return 2*self.r*pi

#实例化一个圆
circle = Circle(1)  #实例化半径为1的圆
print(circle.area)  #直接调用圆面积计算的方法返回圆面积
print(circle.perimeter) #直接调用圆周长的方法返回圆周长
伪装成属性后修改属性的值
  • 通过这种方法修改了私有变量的值
  • 被修饰的两个方法的名最好和私有变量名一样,这样伪装的才能彻底
    • 私有变量的查看、修改、删除

        class Father():
            def __init__(self, name):
                self.__name = name
      
            #查看
            @property   #伪装装饰方法成属性
            def name(self):
                return self.__name
      
            #修改
            @name.setter    #提供可修改的方法,装饰器的名字必须是伪装方法的名字.setter
            def name(self, newName):
                self.__name = newName
      
            #删除
            @name.deleter   #提供del调用的方法,并不提供删除
            def name(self, newName):
                print('测试的代码,测试不删除')    #这是测试的代码
                del self__name  #这里才是提供删除的原因
      
        c = Father(1)
        print(c.name)
        c.name = 2  #可以修改__name的属性
        print(c.name)   
        del c.name  #使用del可以调用@deleter装饰的函数
        print(c.name)   
        #结果
        1
        2   
        测试的代码,测试不删除
        报错,找不到_Father__name

类方法classmethod

  • 只涉及静态属性的时候使用

      #建立一个货物的类
      class Goods():
          __discount = 0.5    #这个类具有折扣的通用属性
          def __init__(self, name, price):
              self.name = name    #商品名
              self.__price = price    #商品价格,私有变量,不想让其他人看到
    
          @property   #伪装属性用于查看   
          def price(self):
              return self.__price * Goods.__discount
    
          @classmethod    #类方法
          def change_discount(cls, new_discount): #cls参数指代Goods,指代类名,可以是其他参数但是不建议改变
              cls.__discount = new_discount
    
      #直接外部修改类的通用属性
      Goods.change_discount(0.8)  #将折扣0.5变成0.8,直接调用类名.函数名修改类方法

静态方法staticmethod

  • 可以省略参数self创建类中的方法
  • 在完全面向对象的程序中
  • 如果一个函数即和对象没有关系也和类没有关系
  • 静态方法和静态属性对象都能够调用的,不过一般情况下推荐用类名调用

      class Login():
          def __init__(self, name, password):
              self.name = name
              self.password = password
    
          @staticmethod   #静态方法
          def get_us_pw():    #注意这里没有参数self
              user = input('User:')
              password = input('Password')
              Login(name, password)
    
      #调用
      Login.get_us_pw()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值