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~
图跑了