面向对象是一种抽象化的编程思想。
面向对象就是讲将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么。
面向对象的三大特性:
- 封装将属性和方法书写到类的里面的操作即为封装封装可以为属性和方法添加私有权限
- 继承子类默认继承父类的所有属性和方法子类可以重写父类的属性和方法新式类的继承,采用广度优先的搜索方式
- 多态传入不同的对象,产生不同的结果
在面向对象编程过程中,有两个重要的组成部分:类和对象。
如果大家在学习中遇到困难,想找一个Python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
类和对象的关系:用类去创建一个对象
- 类:类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。特征即是属性行为即是方法
- 对象:对象是类创建处理的真实存在的事物开发中,先有类,再有对象
- 经典类或旧式类不由任意内置类型派生出的类,称之为经典类:python2.0默认类为经典类class 类名: 代码 ...... 新式类: python3.5以上默认类为新式类class 类名(object): 代码
- 定义类语法:class 类名(): 代码 ...... # 注意: 类名要满足标识符命名规则,同时遵循大驼峰命名习惯 例如:class Washer(): def wash(self): print('我会洗衣服')
- 创建对象(对象又名实例)语法:对象名 = 类名() 例如:# 创建对象 haier1 = Washer() # <__main__.Washer object at 0x00000159A7D124E0> print(haier1) # haier对象调用实例方法 haier1.wash()
- self: self指的是调用该函数的对象# 1. 定义类 class Washer(): def wash(self): print('我会洗衣服') # <__main__.Washer object at 0x0000027548F424E0> print(self) # 2.创建对象 haier1 = Washer() # <__main__.Washer object at 0x0000018AEC932518> # haier1对象调用实例方法 haier1.wash() haier2 = Washer() # <__main__.Washer object at 0x0000018AEC932518> haier2.wash()
属性即是特征
对象属性即可以在类外面添加和获取,也能在类里面添加和获取。
- 类外面添加对象属性语法:对象名.属性名 = 值 例如:haier1.width = 500 haier1.height = 800
- 类外面获取对象属性语法:对象名.属性名 例如:print(f'haier1洗衣机的宽度是{haier1.width}') print(f'haier1洗衣机的高度是{haier1.height}')
- 类里面获取对象属性语法:self.属性名 例如:# 定义类 class Washer(): def print_info(): # 类里面获取实例属性 print(f'haier1洗衣机的宽度是{haier1.width}') print(f'haier1洗衣机的高度是{haier1.height}') # 创建对象 haier1 = Washer() # 添加实例属性 haier1.width = 500 haier1.height = 800 # python 可以给类对象动态的添加属性
- 类属性设置和访问类属性类属性就是类对象所拥有的属性, 它被该类的所有实例对象所共有类属性可以使用类对象或实例对象访问class Dog(object): tooth = 10 wangcai = Dog() xiaohei = Dog() print(Dog.tooth) # 10 print(wangcai.tooth) # 10 print(xiaohei.tooth) # 10 # 类属性的优点 # 类的实例记录的某项数据始终保持一致时,则定义类属性 # 实例属性要求每个对象为其单一开辟一份内存空间来记录数据, 而类属性为全类所共有,仅占用一份内存,更加节省内存空间 修改类属性类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性class Dog(object): tooth = 10 wangcai = Dog() xiaohei = Dog() # 修改类属性 Dog.tooth = 12 print(Dog.tooth) # 12 print(wangcai.tooth) # 12 print(xiaohei.tooth) # 12 # 不能通过对象修改属性, 如果这样操作,实则是创建了一个实例属性 wangcai.tooth = 20 print(Dog.tooth) # 12 print(wangcai.tooth) # 20 print(xiaohei.tooth) # 12
- 实例属性class Dog(object): def __init__(self): self.age = 5 def info_print(self): print(self.age) wangcai = Dog() print(wangcai.age) # 5 # print(Dog.age) # 报错: 实例属性不能通过类访问 wangcai.info_print() # 5
- 类方法类方法的特点第一个形参是类对象的方法需要用装饰器@classmethod来标识其为类方法, 对于类方法,第一个参数必须是类对象, 一般以cls作为第一个参数类方法的使用场景当方法中需要使用类对象(如访问私有类属性等)时, 定义类方法类方法一般和类属性配合使用class Dog(object): __tooth = 10 @classmethod def get_tooth(cls): return cls.__tooth wangcai = Dog() result = wangcai.get_tooth() print(result) # 10
- 静态方法静态方法的特点需要通过装饰器@staticmethod来进行装饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)静态方法也能够通过实例对象和类对象去访问静态方法使用场景当方法中即不需要使用实例对象(如实例对象,实例属性), 也不需要使用类对象(如类属性,类方法,创建实例等)时,定义静态方法取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗class Dog(object): @staticmethod def info_print(): print('这是一个狗类, 用于创建狗实例') wangcai = Dog() # 静态方法既可以使用对象访问又可以使用类方法 wangcai.info_print() Dog.info_print()
在Python中,__xx__()的函数叫做魔法方法指的是具有特殊功能的函数
- __ init __(): 初始化对象__init__()方法, 在创建对象时默认被调用,不需要手动调用__init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去
class Washer():
# 定义__init__,添加实例属性
def __init__(self):
# 添加实例属性
self.width = 500
self.height = 800
def print_info(self):
# 类里面调用实例属性
print(f'洗衣机的宽度是{self.width},高度是{self.height}')
haier1 = Washer()
haier1.print_info()
- 带参数的__init__()
class Washer(): def init(self, width, height): self.width = width self.height = height
def print_info(self):
print(f'洗衣机的宽度是{self.width}')
print(f'洗衣机的高度是{self.height}')
haier1 = Washer(10, 20) haier1.print_info()
haier2 = Washer(30, 40) haier2.print_info()
* \_\_str\_\_(): 当使用print()输出对象的时候,默认打印对象的内存地址。如果类定义了_\_str\_\_方法,那么就会打印从这个方法中return 的数据
```python
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return '这是海尔洗衣机的说明书'
haier1 = Washer(10, 20)
# 这是海尔洗衣机的说明书
print(haier1)
- __del__(): 当删除对象时, python解释器会默认调用__del__()方法class Washer(): def __init__(self, width, height): self.width = width self.height = height def __del__(self): print(f'{self}对象已经被删除') haier1 = Washer(10, 20) # 对象<__main__.Washer object at 0x000002204F592358>已经被删除 del haier1
- __dict__(): 类的属性(包含一个字典,由类的数据属性组成)class A(object): a = 0 def __init__(self): self.b = 1 aa = A() # 返回类内部所有属性和方法对应的字典 print(A.__dict__) # 返回实例属性和值组成的字典 print(aa.__dict__)
- 继承的概念是指一个对象直接使用另一对象的属性和方法Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性的方法查看子类所继承的所有父类以及层级关系: print(子类名.__mro__)# 父类A class A(object): def __init__(self): self.num = 1 def info_print(self): print(self.num) # 子类B class B(A): pass result = B() result.info_print() # 1 # 在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫派生类
- 单继承一个子类可以继承一个父类是单继承# 1. 师父类 class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') # 2. 徒弟类 class Prentice(Master): pass # 3. 创建对象daqiu daqiu = Prentice() # 4. 对象访问实例属性 print(daqiu.kongfu) # 5. 对象调用实例方法 daqiu.make_cake()
- 多继承一个子类可以继承多个父类是多继承# 师父类 class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') # 创建学校类 class School(object): def __init__(self): self.kongfu = '[黑马煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') # 徒弟类 class Prentice(Master, School): pass daqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake()
- 子类重写父类的同名属性和方法# 师父类 class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') # 创建学校类 class School(object): def __init__(self): self.kongfu = '[黑马煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') # 徒弟类 class Prentice(Master, School): def __init__(self): self.kongfu = '[独创煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') daqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake() print(Prentice.__mro__) # 子类和父类具有同名属性和方法,默认使用子类的同名属性和方法
- 子类调用父类的同名属性和方法class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[黑马煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' def make_cake(self): # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化 self.__init__() print(f'运用{self.kongfu}制作煎饼果子') # 调用父类方法, 但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) daqiu = Prentice() daqiu.make_cake() daqiu.make_master_cake() daqiu.make_school_cake() daqiu.make_cake()
- 多层继承class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class School(object): def __init__(self): self.kongfu = '[⿊⻢煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' def make_cake(self): self.__init__() print(f'运⽤{self.kongfu}制作煎饼果⼦') def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) # 徒孙类 class Tusun(Prentice): pass xiaoqiu = Tusun() xiaoqiu.make_cake() xiaoqiu.make_school_cake() xiaoqiu.make_master_cake()
- super(): super()调用父类方法class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class School(Master): def __init__(self): self.kongfu = '[⿊⻢煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') # 方法2.1 # super(School, self).__init__() # super(School, self).make_cake() # 方法2.2 super().__init__() super().make_cake() class Premtice(School): def __init__(self): self.kongfu = '[独创煎饼果子技术]' def make_cake(self): self.__init__() print(f'运用{self.kongfu}制作煎饼果子') # 子类调用父类的同名方法和属性: 把父类的同名属性和方法再次封装 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) # 一次性调用父类的同名属性和方法 def make_old_cake(self): # 方法一: 代码冗余; 父类类名如果变化, 这里的代码需要频繁修改 # Master.__init__(self) # Master.make_cake(self) # School.__init__(self) # School.make_cake(self) # 方法二: super() # 方法2.1 super(当前类名, self).函数() # super(Prentice, self).__init__() # super(Prentice, self).make_cake() # 方法2.2 super().函数 super.__init__() super.make_cake() daqiu = Prentice() daqiu.make_old_cake() # 注意: 使用super()可以自动查找父类,调用顺序遵循__mro__类属性的顺序. 比较适合单继承使用
- 私有属性和私有方法定义私有属性和方法: 在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类class Master(object): def init(self): self.kongfu = '[古法煎饼果⼦配⽅]'def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦')class School(object): def init(self): self.kongfu = '[⿊⻢煎饼果⼦配⽅]'def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦')class Prentice(School, Master): def init(self): self.kongfu = '[独创煎饼果子配方]' # 定义私有属性 self.__money = 2000000# 定义私有方法 def __info_print(self): print(self.kongfu) print(self.__money) def make_cake(self): self.__init__() print(f'运用{self.kongfu}制作煎饼果子') def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self)徒孙类class Tusun(Prentice): passdaqiu = Prentice()对象不能访问私有属性和私有方法print(daqiu.__money)daqiu.__info_print()xiaoqiu = Tusun()子类无法继承父类的私有属性和私有方法print(xiaoqiu.__money) # 无法访问实例属性__moneyxiaoqiu.__info_print()注意: 私有属性和私有方法只能在类里面访问和修改 2. 获取和修改私有属性值:在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值 ```python class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class School(object): def __init__(self): self.kongfu = '[⿊⻢煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' # 定义私有属性 self.__money = 2000000 # 获取私有属性 def get_money(self): return self.__money # 修改私有属性 def set_money(self): self.__money = 500 def __info_print(self): print(self.kongfu) print(sekf.__money) def make_cake(self): self.__init__() print(f'运⽤{self.kongfu}制作煎饼果⼦') def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) # 徒孙类 class Tusun(Prentice): pass daqiu = Prentice() xiaoqiu = Tusun() # 调用get_moen函数获取私有属性money的值 print(xiaoqiu.get_money()) # 调用set_moeny函数修改私有属性money的值 xiaoqiu.set_money() print(xiaoqiu.get_money())
- 多态的概念:多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)定义: 多态是一种使用对象的方式, 子类重写父类方法, 调用不同子类对象的相同父类方法,可以产生不同的执行结果好处:调用灵活,有了多态,更容易编写出通用的代码, 做出通用的编程,以适应需求的不断变化实现步骤:定义父类,并提供公共方法定义子类, 并重写父类方法传递子类对象给调用者,可以看到不同子类的执行效果不同
- 例如:class Dog(object): def work(self): # 父类提供统一的方法,哪怕是空方法 print('指哪打哪...') class ArmyDog(Dog): # 继承Dog类 def work(self): # 子类重写父类同名方法 print('追击敌人...') class DrugDog(Dog): def work(self): print('追查毒品...') class Person(object): def work_with_dpg(self, dog): # 传入不同的对象,执行不同的代码,即不同的work函数 dog.work() ad = ArmyDog() dd = DrugDog() daqiu = Person() daqiu.work_with_dog(ad) daqiu.work_with_dog(dd)
- __call__方法的使用__call__方法:一个类里面一旦实现了__call__方法那么这个类创建的对象就是一个可调用对象,可以像调用函数一样进行调用
- 什么是property属性property属性就是负责把类中的一个方法当做属性进行使用,这样做可以简化代码的使用class Person(object): def __init__(self): self.__age = 0 # 装饰器方式的property, 把age方法当做属性来使用,表示当获取属性时会执行下面修饰的方法 @property def age(self): return self.__age 定义property属性有两种方式:装饰器方式类属性方式
- 装饰器方式class Person(object): def __init__(self): self.__age=0 # 装饰器方式的property,把age方法当做属性来使用, 表示获取属性时会执行下面修饰的方法 @property def age(self): return self.__age # 把age方法当做属性来使用, 表示当设置属性时会执行下面修饰的方法 @age.setter def age(self,new_age): if new.age >= 150: print('成精了') else: self.__age = new_age @property表示把方法当做属性来使用,表示当获取属性的会执行下面修饰的方法@方法名.setter表示把方法当做属性来使用, 表示当设置属性的时候会执行下面修饰的方法装饰器方式的property属性修饰的方法名一定要一样
- 类属性方式property属性 = property(获取值方法, 设置值方法)property的参数说明:第一个参数是获取属性时要执行的方法第二个参数是设置属性时要执行的方法class Person(object): def __init__(self): self.__age=0 def get_age(self): """当获取age属性的时候会执行该方法""" def set_age(self, new_age): """当设置age属性的时候会执行该方法""" if new_age > 150: print('成精了') else: self.__age = new_age # 类属性方式的property属性 age = property(get_age, set_age)
最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
,