面向对象三大特征
1.封装
对类中成员属性和方法的保护,控制外接对内部成员的访问、修改和删除等操作。
1. 类中封装了什么
成员属性
成员方法
2. 封装等级
- 公有:公有成员既能够在类外调用,又能在类内调用
- 私有:私有成员不能在类外调用,可以在类内调用
3. 类中的绑定方法(方法在类的内部,MyCar内部、外部)
-
绑定到对象(对象调用方法时,系统自动把该对象当成参数进行传递)
-
绑定到类(对象或者类调用方法时,系统西东把该类当成参数进行传递
class MyCar():
# 公有成员属性
color = "green"
# 私有成员属性
__logo = "tesila"
# 公有成员方法
def drive(self):
print("keyikaiche")
# 私有成员方法
def __info():
print("jiagebaomi,youhaobaomi")
# 类的实例化
obj = MyCar()
# 对象的相关操作
# 实例化的对象访问公有成员属性和方法
# 调用属性
print(obj.color) # green
## 调用方法
obj.drive()
# 调用私有成员:私有成员
obj.__logo()
# 实例化的对象动态添加公有成员属性和方法
# 添加成员属性
obj.color = "black"
# __dict__ 查看对象或者类当中的成员,返回一个字典
print(obj.__dict__) # black
print(obj.color) # black
## 添加成员方法
# 1.动态添加无参方法
def dahuangfeng():
print("bianxing")
# 对象.属性(自定义)= 方法
obj.dahuangfeng = dahuangfeng
obj.dahuangfeng()
# 2.动态添加有参方法
def qingtianzhu(name):
print("bianxing,qingtianzhu,{}".format(name))
# 对象.属性(自定义的)= 方法
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu('擎天柱')
# 改造2 低级版
def qingtianzhu(obj,name):
print("bianxing,qingtianzhu,{}".format(name))
print("bianxing,qingtianzhu,{},{}".format(name,obj.color))
# 对象.属性(自定义的)= 方法
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu(obj,'擎天柱')
# 改造3 高级版 (创建一个绑定方法,自动传递obj对象)
# 在类外,让系统自动帮助传递obj这个对象参数
# types 模块下的MethodType方法,创建一个绑定方法,自动传递obj对象
import types
def qingtianzhu(self,name):
print("bianxing,qingtianzhu,{},{}".format(name,self.color))
obj.qingtianzhu = types.MethodType(qingtianzhu,obj)
obj.qingtianzhu("擎天柱")
## 动态添加lambda 匿名函数
obj.weizhentian = lambda : print("bianxing,weizhentian")
obj.weizhentian()
# 查看obj成员,修改后的
print(obj.__dict__)
4.类的相关操作
class MyCar():
oil = "2.0T"
__price = "5000W"
def oil_info(self):
print("我的油耗是100L,发动机是2.0T")
def __price_info():
print("我的价格信息")
"""
obj = MyCar()
# 为什么调用失败?因为该公有方法没有参数
obj.oil_info()
"""
## 类的相关操作
# 1.定义的类访问公有成员属性和方法
print(MyCar.oil)
# MyCar.__price error
MyCar.oil__info() okde
# 2.定义的类动态添加公有成员属性和方法
# 添加公有成员属性
MyCar.logo = "兰博基尼"
print(Mycar.__dict__)
# 添加公有成员方法(无论是对象还是类,我们在类外添加的方法都是公有的)
# 1.动态添加公有无参数的方法
def fangxiangpan():
print("制造方向盘的方法")
# 类.成员(自定义的名字) = 方法
MyCar.fangxiangpan = fangxiangpan
MyCar.fangxiangpan()
# 2.动态添加公有有参方法
def engine():
print("我的发动机是%s"%(dongli))
MyCar.engine = engine
MyCar.engine("四缸发动机")
# 3.动态添加lambda表达式
MyCar.luntai = lambda pinpai : print("我的轮胎品牌是%s"% pinpai)
MyCar.luntai("miqilin")
print(MyCar.__dict__)
"""
# 能否调用成功?类中成员只归属当前这个类本身,对象可以调用其中的公有成员,但是没有修改和删除的权利,因为都归属于类,不是对象中的
# 类无法调用对象中的相关成员,但是对象可以调用类中的相关成员
"""
# 对象调用类中的成员
"""调用对象中的成员时,先看看自己有没有该成员,如果有,那么就先调用自己的,如果没有,那就调用类的"""
obj2 = MyCar()
print(obj2.logo)
# 类调用对象中的成员
print(MyCar.logo) # 兰博基尼
5.类中的私有成员
# 私有成员改名策略 [_类名__c成员名]
# 利用类内的公有方法间接调用私有成员或方法(推荐)
## 删除相关成员
# 1.实例化的对象删除公有成员属性和方法
obj.captain = "wangsicong"
print(obj.__dict__) # wangsicong
del obj.captain
print(obj.__dict__)
# 如果对象中有该成员,先调用自己的,没有的话,调用类的,如果都没有,报错
print(obj.captain) # chushijitou
# 删除方法
obj.func = lambda : print("kaifeijishiweile")
obj.func()
plane.func() # 类中没有这个方法,所有报错了
del obj.func
obj.func # 已删,error
# 2.定义的类删除公有成员属性和方法
# 删除属性
del plane.captain
print(plane.captain) Error
obj.captain # Error 对象和类中,哪里都没有这个captain成员
# 删除方法
del plane.fly
obj.fly() # Error
7.魔术方法(特定实际自动触发)
# __init__ (构造方法)
"""为对象添加成员,参数是不固定的,至少有一个self参数,没有返回值"""
# 基本语法
def MyClass():
# 触发时机,在实例化的时候自动触发
def __init__(self):
self.name = "zhangjie"
# 常规写法
obj = MyClass() # 实例化
# obj.name = "zhangjie"
print(obj.name)
# 2 带有多个参数的构造方法
class MyClass():
def __init__(self,name):
# 对象.成员属性(自定义的)= 参考值
self.name = name
# 如果构造方法里面含有额外参数,在实例化的时候,需要传参
obj = MyClass("李博") # 这里写什么,最后就会打印什么,就会灵活
print(obj.name)
# 3 类可以是一个,对象可以是多个,可以通过一个类实例化多个不同的对象,每创建一个对象,都会单独占用一个空间,创建的越多,占用的空间就越大
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin
def cry(self):
print("小孩会哭")
def drink(self):
print("喝奶")
def __eat(self):
print("吃手指")
def pub_func(self):
print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin))
# print("该对象的名字是{},该对象的肤色是{}".format(name,skin))
# 这么写是错的
# 创建一个对象
afanda = Children("wangtiechui","blue")
afanda.cry() # ok
afanda.pub_func() # ok
# 创建第二个对象
dan = Children("someone","black")
dan.drink() # ok
dan.pub_func() # ok
# 创建第三个对象
bao = Children("baoqiang","green")
bao.pub_func()