1 """ 2 面向对象(上) 3 """ 4 """ 5 类:一类事物的统称,名词 6 类的实例对象:类所对应的实际物体 7 8 类的定义格式: 9 class 类名(父类名): 10 属性-->变量,静态特征 11 方法-->函数,动态行为 12 说明: 13 1. 声明一个类需要使用 class 关键字; 14 2. 类名首字母一定要大写,大驼峰式命名规则; 15 3. 父类名,当前类如果继承自其他的类,被继承的类就是父类,需要写在此处括号中, 16 当前类就是父类的子类。 17 如果没有继承自其他的类,此处括号可以空着,或着写object,或着不写括号。 18 所有的类都是继承自object类。 19 4. 属性: 20 4.1 类属性:定义在类中,方法外的属性。供所有的对象共有。 21 使用:1. 类名.类属性名(推荐) 2. 实例名.类属性名 22 修改:1)类名.类属性名=值 23 2)实例对象不能修改类属性,如果写成 实例名.类属性名=值 形式,认为创建了一个新的实例属性。 24 可以在类中进行定义(修改,删除) 25 也可以在类外使用类名进行修改 26 4.2 实例属性:定义在类的方法中的属性,每个实例对象单独拥有,互相独立互不干预 27 使用: 实例名.属性名 (先调用方法) (类不能单独调用实例属性) 28 修改: 实例名.属性名=值 29 增加: 实例名.属性名=值 30 比较灵活,可以在类的方法中定义(修改,删除) 31 也可以在类的外边使用对象来添加或修改或删除 32 5. 方法: 33 5.1. 类方法 34 5.2. 实例(对象)方法,第一个参数为self, 35 实例对象可以直接调用,-->对象名.方法名(实参) tom.eat("orange", "bread") 36 类也可以调用,-->类名.方法名(对象实例,实参) Cat.eat(tom,"orange", "bread") 37 5.3. 静态方法 38 39 实例的定义: 40 先定义类再定义类的实例对象。 41 格式:实例名=类名() 42 43 必须要先定义实例对象,然后使用实例对象调用实例方法,才能使用实例属性。 44 45 二 self 46 1.在对象方法列表中,第1个参数永远是self 47 2.self的字面意思是自己,表示是对象本身 48 3.当某个对象调用方法的时候,python届时起会把这个对象作为第1个参数传给self, 49 开发者只需要传递后面的参数就可以了 50 三 类调用对象方法 51 类也可以调用对象方法,只需要在调用的时候传入类或者该类的对象即可 52 53 四 在类的方法中,有两种特殊的方法,分别在类创建和销毁的时候调用.(魔法方块) 54 1.构建方法__init__(self,形参) 类创建对象的时候调用,初始化 55 2.析构方法__del__(self) 作用:销毁对象释放资源 56 a.对象销毁时间自动执行,括号中只跟一个self 57 b.使用del删除对象时,也会自动调用 58 五 在python类中,一共在三种方法,分别是: 59 1.对象方法:第一个参数是self,self:对象实例来调用方法 60 2.类方法:第一个参数是cls,cls:类所拥有的的方法,使用@classmethod修饰 61 类能调用,对象也能调用。 62 (虽然叫做类方法,但是对象和类都可以调用,当对象调用类方法时) 63 系统自动将对象所属的类作为第一个默认参数传入。 64 3.静态方法:静态方法没有self,cls参数,在静态方法中无法访问实例属性, 65 不可以直接访问类属性,但是可以通过类名引用类属性 66 (静态方法跟定义它的类没有直接关系,只是起到了类似函数的作用) 67 """ 68 """ 69 第十章 面向对象(下) 70 一 面向对象的三大特征: 71 1.封装:把定义在类中的 属性和方法 设为私有,在类的外边无法直接访问 72 私有方法和私有属性,在前边加上两个下划线(__name __say()) 73 私有属性,可以定义普通的方法来实现在类的外边对其赋值和调用 74 私有方法,在类中进行访问 75 Python中没有绝对的私有的,这种方法只是限制访问 76 如果在类的外边非要强行访问私有属性或方法,__类名__属性名/方法名,这种方式 77 尽量不要用。 78 当我们给属性或方法加上双下划线后,python解释器其实是在其名称的前边做了一些 79 处理,加上了一个下划线和类名,使得我们在外边只写原名无法直接访问 80 """ 81 """ 82 1.继承:一个类可以继承自另一个类,并自动拥有了另一个类的属性和方法 83 并且可以进一步完善,添加新的特性和方法 84 2.当一个类继承自其他类时,继承类叫作子类,被继承类叫作超类或者父类。 85 例如,类B继承自类A,则类B为子类,类A叫作超类或者父类。 86 分 单继承 多继承 87 3.关于类和对象,有两个函数: 88 1)isinstance(对象名,类名) -->True/False 判断对象是否是该类的实例化对象 89 2) issubclass(子类名,父类名) -->True/False 判断子类是否继承自该父类 90 4.多继承:一个子类继承多个父类,子类的对象同时拥有多个父类的属性和方法 91 5.如果多个父类之间有重名的方法或属性,哪个父类写在前边优先被子类继承 92 eg. class Flyfish(Bird,Fish) # Bird写在前边,它优先 93 pass 94 但是当子类继承自多个父类,想要精确调用其中某个父类的某个方法,解决方式: 95 5.1 在子类的定义中,写明使用哪个方法。比如:breathe = Bird.Breathe 96 5.2 在对象调用方法时,指明调用哪个父类的哪个方法。比如:Fish.breathe(ff) 97 6.子类可以重写父类的方法,重写完之后还想使用父类的同名方法,supper() 98 格式:supper(子类名,self).__init__(参数1,参数2,参数n) 99 一般会重写构造方法。 100 """ 101 102 # class Person(object): # 定义了一个人类 103 # legs = 2 # 类属性,所有的实例对象所共有。 104 # 105 # # 定义了一个实例方法,第一个参数永远是self,代表实例本身。food形参。 106 # def eat(self, food): 107 # # 定义了一个实例属性,实例属性的值等于eat方法接收到的food参数。 108 # self.love_food = food # 每个实例对象所拥有 109 # 110 # 111 # xiao_ming = Person() # 定义了一个人类的实例对象,xiao_ming 112 # xiao_ming.eat("苹果") # 实例对象来调用实例方法,并把"苹果"实参传给love_food 113 # print(xiao_ming.legs) # 使用对象来访问类属性 114 # print(xiao_ming.love_food) # 使用对象来访问实例属性 115 # 116 # xiao_fang = Person() # 定义了一个人类的实例对象,xiao_fang 117 # xiao_fang.eat("香蕉") # 实例对象来调用实例方法,并把"香蕉"传给love_food 118 # print(xiao_fang.legs) # 使用对象来访问类属性 119 # print(xiao_fang.love_food) # 使用对象来访问实例属性 120 # 121 # xiao_ming.love_drink = "橙汁" # 实例名.属性名=值,添加了实例属性.不推荐。只有当前对象拥有。 122 # print(xiao_ming.love_drink) 123 # 124 # # print(xiao_fang.love_drink) # AttributeError: 'Person' object has no attribute 'love_drink' 125 # xiao_ming.love_drink = "梨汁" # 修改对象属性的值 126 # print(xiao_ming.love_drink) 127 # 128 # print(Person.legs) # 类名访问类属性 129 # Person.legs = 4 # 使用类名修改类属性 130 # print(xiao_fang.legs) # 4 131 # print(xiao_ming.legs) # 4 132 # 133 # xiao_fang.legs = 3 # 使用实例名.类名=值,创建了一个新的对象属性 134 # print(xiao_fang.legs) # 3 # 对象属性与类属性重名,对象优先使用对象属性的值。 135 # print(xiao_ming.legs) # 4 136 137 # class Cat(): 138 # legs = 4 # 类属性 139 # name = "AI_student" 140 # # eyes = 2 # 类属性 141 # def __init__(self,logo,age): # 构造方法,类创建对象时自动调用 142 # print("__init__方法自动执行") 143 # self.logo = logo 144 # self.age = age 145 # self.skill = None # 小猫刚出生没有捉老鼠的技能,先赋值为None 146 # print(self,"对象创建了") 147 # def __del__(self): # 构造方法,对象被销毁时自动执行 148 # print("__del__构造方法自动执行") 149 # print(self,"被销毁") # * 150 # # def eat(self,drink,food): # 对象方法 151 # # print("我是类中的对象方法") 152 # # print("self现在的值是", self) 153 # # self.my_drink = drink # 对象属性 = 参数 154 # # self.my_food = food # 对象属性 = 参数 155 # # # self.skill = None # 小猫刚出生没有捉老鼠的技能,先赋值为None 156 # # return "aaa" 157 # # def des(self,name,color): # 对象方法 158 # # print("self现在的值是", self) 159 # # self.name = name 160 # # self.color = color 161 # 162 # # tom = Cat() 163 # # print(tom.legs) # 对象可以调用类属性 164 # # print(tom.eyes) 165 # # print(tom.legs) # 类可以调用类属性 166 # # # 先用实例来调用实例方法,才能使用方法中的实例属性 167 # # tom.des("汤姆", "白色") 168 # # print(tom.name) # AttributeError: 'cat' object has no attribute 'name' 169 # # print(tom.color) # AttributeError: 'cat' object has no attribute 'name' 170 # # 171 # # # 类不能直接调用实例属性 172 # # # print(cat.name) # AttributeError: type object 'cat' has no attribute 'name' 173 # # 174 # # jack = Cat() 175 # # 176 # # # 在类的外边,修改类属性,使用类名来修改 177 # # Cat.legs = 3 178 # # print(tom.legs) 179 # # print(jack.legs) 180 # # 181 # # # 在类的外边使用对象来修改类属性:添加一个新的对象属性 182 # # # 对象的 对象属性和类属性重名时,对象名.属性名时 调用的是对象属性 183 # # jack.legs = 5 184 # # print(tom.legs) # tom调用类属性legs 185 # # print(jack.legs) # jack调用自己的对象属性legs 186 # # 187 # # 188 # # resuit = tom.eat("橙汁", "鱼") # 调用对象方法,并把方法的返回值接收到 189 # # print(resuit) 190 # # tom.skill = "climb" # 调用完方法后,给其中的一个对象属性修改值 191 # # print("名字为%s的%s颜色的猫,爱喝%s,爱吃%s,拥有%s技能" % 192 # # (tom.name,tom.color,tom.my_drink,tom.my_food,tom.skill)) 193 # # 194 # # tom.play = "game" # 添加tom对象的对象属性play,赋值"game" 195 # # tom.play = "games" # 修改对象属性 196 # # print(tom.play) # tom的属性 197 # # # print(jack.play) # jack没有play属性 198 # # 199 # # Cat.play = "game111" # 在类的外边添加了一个类属性 200 # # print(jack.play) 201 # # 202 # # del Cat.play # 在类的外边删除类属性 203 # # # print(jack.play) # 类属性已经被删除,不能在访问到 204 # # 205 # # del tom.play # 在类的外边使用对象删除对象属性 206 # # # print(tom.play) # 对象属性已经被删掉,不能再访问到 207 # 208 # # jack = Cat() 209 # # jack.eat("牛奶", "面包") 210 # # print(jack.my_drink) 211 # # print(jack.my_food) 212 # # jack.des("杰克", "black") 213 # # print(jack.name) 214 # # print(jack.color) 215 # # 216 # # tom = Cat() 217 # # tom.eat("coffee", "饼干") # 推荐使用 218 # # print(tom.my_drink) 219 # # print(tom.my_food) 220 # # tom.des("汤姆", "while") 221 # # print(tom.name) 222 # # print(tom.color) 223 # # 224 # # Cat.eat(jack,"milk", "bread") # 使用类来调用对象方法,不常用 225 # # print(jack.my_drink) 226 # # print(jack.my_food) 227 # tom = Cat("汤姆",3) # 定义对象时传入实参给__init__ * 228 # print("我的名字是%s" % tom.name) 229 # print("我的名字是%d" % tom.age) 230 # 231 # jack = Cat("杰克",4) 232 # print("我的名字是%s" % jack.name) 233 # print("我的名字是%d" % jack.age) 234 # 235 # del tom # 手动删除对象时,也会自动调用__del__方法 删除tom对象 236 # print("程序执行结束") 237 238 # class Employee: 239 # level = 3 # 类属性 240 # def WorkforOneyear(self): # 对象方法 241 # self.level = 4 # 同名的对象属性 242 # 243 # 244 # xiao_ming = Employee() # 定义了一个类的对象xiao_ming 245 # print(xiao_ming.level) # 使用对象实例调用类属性 246 # # 1.使用对象方法 方式1 使用对象实例来调用对象方法 247 # xiao_ming.WorkforOneyear() 248 # # 2.使用对象方法 方式2 使用类把实例对象作为参数传递来调用对象方法 249 # Employee.WorkforOneyear(xiao_ming) 250 # print(xiao_ming.level) # 对象属性-->4. (同名的对象属性覆盖了类属性) 251 252 # class Apple(object): 253 # _count = 5.5 # 类属性 * 254 # __name = "app" # 私有属性 ** 255 # # def add_one(self): # 对象方法 256 # # self.count = 1 # 与上边的类属性同名的对象属性 257 # # @classmethod 258 # # def add_two(cls): # 类方法 259 # # cls.count = 2 # 修改类属性的值为2 260 # # print("__类方法__") 261 # # print(cls) 262 # # @staticmethod # * 263 # # def static_method(num): # 静态方法,类似于函数 264 # # print("这是静态方法",num) 265 # # print(Apple.count) # 不可以直接访问类属性,但是可以通过类名引用类属性 266 # # result = Apple.count + num 267 # # print(result) 268 # def _eat(self): # ** 269 # print("苹果很好吃") 270 # def __drink(self): # 私有方法 271 # print("苹果可以做成果汁") 272 # 273 # apple = Apple() # apple为实例对象 * ** 274 # # print(Apple.count) # -->0 275 # # apple.add_one() # 实例来调用对象方法 276 # # print(Apple.count) # -->0 277 # # print(apple.count) # -->1 278 # # print("=" * 30) 279 # # Apple.add_two() # 方式1 类来调用类方法,推荐 280 # # print("=" * 30) 281 # # apple.add_two() # 方式2 对象来调用类方法 282 # # print("=" * 30) 283 # # print(Apple.count) # -->2 284 # # apple.static_method(18) # 1.使用对象实例调用静态方法 * 285 # # apple.static_method(20) # 2.使用类调用静态方法 286 # 287 # print(apple._count) # 5.5 属性名前加一个下划线,在类的外边可以访问到 ** 288 # # AttributeError: 'Apple' object has no attribute '__name' 289 # # print(apple.__name) # 属性名前加两个下划线,在类的外边不能够直接访问 290 # apple._eat() # 方法前加一个下划线,在类的外边能够访问到 ** 291 # # apple.__drink() # 方法前加两个下划线,在类的外边不能直接访问 292 293 # # 封装案例,私有属性,私有方法,分别在属性的方法的名称前边加上双下划线 294 # class Person(object): 295 # def __init__(self,name): 296 # self.name = name 297 # # self.__age = age # 在属性名前加双下划线,变为私有属性 298 # # 设置私有属性的方法 299 # def Setage(self,age): 300 # if age >= 0 and age <= 110: 301 # self.__age = age # 在属性名前加双下划线,变为私有属性 302 # else: 303 # print("年龄不符合要求") 304 # # 设置获取私有属性方法 305 # def Getage(self): 306 # self.__say() # 在类的方法中访问私有方法 307 # return self.__age # 返回私有属性的值 308 # def __say(self): # 加了双下划线的方法,私有方法,只在类内部使用 309 # print("我是人类,我很聪明") # ** 310 # # 311 # lao_wang = Person("老王") # ** 312 # print(lao_wang.name) 313 # print(lao_wang.age) 314 # lao_wang.age = 300 # 修改对象属性 315 # print(lao_wang.__age) # 没有办法直接访问私有属性 316 # AttributeError: 'Person' object has no attribute '__age' 317 # lao_wang.Setage(30) # 对象来调用普通的对象方法,实现对私有属性的传值- 318 # print(lao_wang.Getage()) # 对象来调用的对象方法, 实现获取私有属性的值 319 320 # AttributeError: 'Person' object has no attribute '_Person__age' 321 322 # 私有方法,在类的外边无法直接访问 323 # lao_wang.__say() # AttributeError: 'Person' object has no attribute '__say' 324 # print(dir(lao_wang)) # **使用dir查看所有对象所拥有的对象和方法,发现私有属性和私有方法的真实名称为:单下划线类名下划线名称 325 # lao_wang.Setage(30) 326 # print(lao_wang._Person__age) # 使用对象直接访问私有属性 327 # lao_wang._Person__say() # 使用对象直接访问私有方法 328 # 继承 329 # class Vehicle(): # 父类/超类 330 # def __init__(self, level=4): 331 # self.level = level 332 # def run(self): 333 # print("我会移动") 334 # def get_Vehicle_color(self, color): 335 # self.color = color 336 # self.__move() 337 # def __move(self): 338 # print("我跑的很快") 339 # 340 # class Car(Vehicle): # 子类 341 # pass 342 # 343 # ao_tuo = Car() # 子类的对象 344 # print(ao_tuo.level) # 子类的对象直接调用父类的属性 345 # ao_tuo.run() # 子类的对象直接调用父类的方法 346 # ao_tuo._Vehicle__move() 347 # ao_tuo.get_Vehicle_color("red") 348 349 350 # class GirlFriend(object): # 类 351 # legs = 2 # 类属性 352 # def __init__(self, name, faceValaue): # 构造方法,创建对象时自动调用 353 # self.name = name # 对象属性 354 # self.faceVacelue = faceValaue # 对象属性 355 # # self.__age = age # 对象属性 356 # self.money = 0 357 # def HouseWork(self): # 对象方法 358 # print("做家务") 359 # def Shopping(self,cost): # 对象方法 360 # print("买买买") 361 # self.money -= cost 362 # def eat(self,food): # 对象方法 363 # self.food = food # 对象属性 364 # def getMoney(self,money): # 对象方法 365 # self.__say() 366 # self.money += money 367 # def __del__(self): # 析构方法 程序结束; 对象被删除 368 # print("走了>>>") 369 # def SetAge(self, age): 370 # if age >= 0 and age<= 110: 371 # self.__age = age 372 # else: 373 # print("年龄不符合要求") 374 # def Getage(self): 375 # return self.__age 376 # def __say(self): # 私有方法 377 # return "这是一个秘密" 378 # # 379 # # 380 # xiao_fang = GirlFriend("小芳", 100) 381 # # print(xiao_fang.name,xiao_fang.legs, 382 # # xiao_fang.faceVacelue,xiao_fang.__age) 383 # # xiao_fang.HousWork() 384 # # # xiao_fang.Shopping() 385 # # xiao_fang.eat("饭") 386 # # print(xiao_fang.food) 387 # # xiao_fang.getMoney(10000) 388 # # print(xiao_fang.money) 389 # # xiao_fang.getMoney(11000) 390 # # print(xiao_fang.money) 391 # # xiao_fang.Shopping(2000) 392 # # print(xiao_fang.money) 393 # # xiao_fang.Shopping(2000) 394 # # print(xiao_fang.money) 395 # xiao_fang.SetAge(20) 396 # print(xiao_fang.Getage()) 397 # # xiao_fang.__say() 398 # xiao_fang.getMoney(15000) 399 # print(xiao_fang.money) 400 # print(xiao_fang._GirlFriend__age) # 强行访问私有属性,最好不这么写 401 # print(xiao_fang._GirlFriend__say()) # 强行访问私有方法,最好不这么写 402 403 """ 404 写一个男朋友类 405 """ 406 # class Person(object): # 父类/超类 407 # def __init__(self,name,age,power): 408 # self.name = name 409 # self.age = age 410 # self.power = power 411 # self.__house = "大别墅" # 父类的私有属性 412 # def getMoney(self,money): 413 # self.getMoney = money 414 # def play(self): 415 # print("play game") 416 # def getHouse(self): # 私有方法,获取私有属性 417 # return self.__house 418 # 419 # class BoyFriend(Person): # 单继承,子类 420 # pass 421 # # def __init__(self,name,age,power): * 422 # # self.name = name 423 # # self.age = age 424 # # self.power = power 425 # # def getMoney(self,money): 426 # # self.getMoney = money 427 # # def play(self): 428 # # print("play game") * 429 # 430 # class GirlFriend(Person): # 单继承,子类 431 # pass 432 # 433 # 434 # xiao_ming = BoyFriend("小明", 25, 90) # 子类的对象 435 # xiao_ming.getMoney(20000) # 子类的对象调用父类的方法 436 # print(xiao_ming.name,xiao_ming.age,xiao_ming.power,xiao_ming.getMoney) 437 # xiao_ming.play() # 子类的对象调用父类的方法 438 # 439 # xiao_fang = GirlFriend("小芳", 20, 90) 440 # xiao_fang.getMoney(10000) 441 # print(xiao_fang.name,xiao_fang.age,xiao_fang.power,xiao_fang.getMoney) 442 # xiao_fang.play() 443 # 444 # 445 # print(xiao_ming.getHouse()) # 子类对象调用父类的普通方法来访问 446 # # 父类的私有属性 447 # print(xiao_fang.getHouse()) 448 # 449 # print(isinstance(xiao_ming,BoyFriend)) # True 450 # print(isinstance(xiao_fang,BoyFriend)) # False 451 # print(isinstance(BoyFriend,Person)) # True 452 453 # 多继承 454 # class Fish(object): 455 # def breathe(self): 456 # print("鱼儿的呼吸方式") 457 # def move(self): 458 # print("鱼儿会在水里游") 459 # 460 # class Bird(object): 461 # def breathe(self): 462 # print("鸟儿的呼吸方式") 463 # def fly(self): 464 # print("鸟会在天空中飞") 465 # 466 # class FlyFish(Fish, Bird): # 子类,有两个父类 467 # breathe = Bird.breathe # 方式1:在类中指明使用哪个父类的方法 468 # 469 # ff = FlyFish() 470 # ff.breathe() # -->鸟儿的呼吸方式 471 # ff.move() # -->鱼儿会在水里游 472 # ff.fly() # -->鸟会在天空中飞 473 # Fish.breathe(ff) # --》鱼儿的呼吸方式 474 475 # 子类重写父类方法 476 # class Fish(object): # 父类 477 # def __init__(self,name,age): 478 # self.name = name 479 # self.age = age 480 # def breathe(self): 481 # print("鱼儿的呼吸方式") 482 # def move(self): 483 # print("鱼儿会在水里游") 484 # 485 # 486 # class Goldfish(Fish): # 子类 487 # def __init__(self,name,age,color): # 重写构造方法 488 # super(Goldfish,self).__init__(name,age) # 使用父类的同名方法 489 # self.color = color # 子类自己属性 490 # 491 # 492 # ff = Goldfish("晶晶",2,"black") 493 # print(ff.name,ff.age,ff.color) 494 # ff.breathe() 495 # ff.move() 496 497 """ 498 作业:思考,如何实现 一个人开始射击 499 需要几个类,每个类都要有哪些方法 500 弹夹: 501 属性:子弹数量 502 行为:无 503 枪类:AK47 504 属性:型号 505 行为:射击 506 人类:姓名 507 行为:开枪,换弹夹,捡枪 508 """ 509 # 弹夹 40发 510 # class BulletBox(object): 511 # def __init__(self,count): 512 # self.bulletCount = count # 弹夹的子弹数量 513 # # 枪类 AK47 M416 514 # class Gun(object): 515 # def __init__(self,type,buBox): 516 # self.type = type # 型号 517 # self.buBox = buBox # 枪的弹夹 518 # def shoot(self): # 射击 519 # if self.buBox.bulletCount > 0: 520 # self.buBox.bulletCount -= 1 521 # print("开枪射击,子弹还剩%d" % (self.buBox.bulletCount)) 522 # else: 523 # print("枪没有子弹了,需要更换弹夹") 524 # # 人类 525 # class Person(object): 526 # def __init__(self,name): 527 # self.name = name # 姓名 528 # self.gun = None # 人一开始没有枪 529 # def fire(self): # 开火 530 # if self.gun is None: 531 # print("你还没有枪,不能开火") 532 # else: 533 # print("%s高喊:冲啊_"% self.name) 534 # self.gun.shoot() # 本类中定义的对象属性去调用另一个类中的方法 535 # # 能实现的前提是,此对象属性要赋值为另一个类的对象实例 536 # def fillBulletBox(self,count): # 换弹夹 537 # self.gun.buBox.bulletCount = count 538 # 539 # fastl = BulletBox(5) # 弹夹对象,一次填充40发子弹 540 # ak_47 = Gun("ak_47",fastl) # 枪的对象,并把弹夹对象作为参数传递 541 # xu_san_duo = Person("许三多") # 人类的对象,许三多 542 # xu_san_duo.gun = ak_47 # 动态修改对象属性的值,并把枪的对象赋给现在这个对象属性 543 # xu_san_duo.fire() 544 # xu_san_duo.fillBulletBox(20) 545 # xu_san_duo.fire() 546 """ 547 多态:一种事物的多种表现形态 548 """ 549 # class Animal(object): 550 # pass 551 # class Rabbit(Animal): 552 # def move(self): 553 # print("兔子蹦蹦跳跳") 554 # 555 # class Soil(Animal): 556 # def move(self): 557 # print("蜗牛慢慢爬") 558 # def test(temp): 559 # temp.move() 560 # peter = Rabbit() 561 # xiao_wo = Soil() 562 # test(peter) 563 # test(xiao_wo) 564 """ 565 多态,一个人喂养不同的动物 566 """ 567 # class Animal(object): 568 # def __init__(self, name): 569 # self.name = name 570 # def eat(self): 571 # print("%s来吃饭" % self.name) 572 # class Rabbit(Animal): 573 # pass 574 # class Cat(Animal): 575 # pass 576 # class Person(object): 577 # def __init__(self,name): 578 # self.name = name 579 # def feed(self,zoo): 580 # print("已准备好食物") 581 # zoo.eat() 582 # Peter = Rabbit("彼德") 583 # tom = Cat("汤姆") 584 # xiao_ming = Person("小明") 585 # xiao_ming.feed(Peter) 586 # xiao_ming.feed(tom) 587 588 """ 589 运算符重载:通过实现特定的方法使类的实例对象支持Python的各种内置操作 590 1.算术运算符重载 591 1.1加法运算符重载 __add__ 592 2.索引分片重载(有序的序列:字符串、列表、元组、range) 593 2.1 __getitem__方法 594 在对实例对象执行索引、分片或者for迭代操作时,会自动调用__gatitem__方法 595 2.2 __setitem__方法 596 通过赋值语句索引或者分片赋值时,调用此方法实现对序列对象的修改 597 2.3 __delitem__方法 598 当调用del方法时,实质上会调用此方法实现删除操作 599 3.定义字符串的显示形式 600 3.1 __str__方法,针对print、str函数起作用 601 3.2 __rapr__方法,对print、str、repr函数起作用,交互环境下 602 同时加载了__str__和__repr__,__str__对print和str函数起作用 603 而__repr__只对repr起作用 604 交互环境下:直接输入对象名回车调用的是__repr__方法 605 606 607 """ 608 # class Person(object): 609 # def __init__(self,name,age,score): 610 # self.name = name 611 # self.age = age 612 # self.score = score 613 # def __add__(self, other): # 加法重载 614 # return self.age + other.age 615 # def __getitem__(self, index): # 索引、分片重载 616 # return self.score[index] 617 # def __setitem__(self, index, value): # 索引、分片赋值重载 618 # self.score[index] = value 619 # def __delitem__(self, key): 620 # del self.score[key] 621 # 622 # 623 # 624 # xiao_ming = Person("小明",20,[100,80,90]) 625 # xiao_fang = Person("小芳",18,[100,100,100]) 626 # # print(xiao_fang.age + xiao_fang.age) 627 # # print(2 + 3) 628 # print(xiao_ming + xiao_fang) 629 # # print(xoap_ming.score[0]) # 对象来调用属性实现 630 # print(xiao_ming[0:2]) # --> getitem 631 # # xiao_ming.score[1] = 88 632 # # print(xiao_ming.score) 633 # xiao_ming[1] = 88 # --> setitem 634 # print(xiao_ming.score) 635 # del xiao_ming[0] # -->delitem 636 # print(xiao_ming[:]) # --> getitem 637 # class Company(object): 638 # def __init__(self,name,boss,emplyee): 639 # self.name = name 640 # self.boss = boss 641 # self.emplyee = emplyee 642 # # def __getitem__(self, item): 643 # # return self.emplyee[item] # 返回emplyee属性的某一个元素 644 # # def __setitem__(self, key, value): 645 # # self.emplyee[key] = value # 给emplyee属性中的某一个元素赋新的值 646 # # def __delitem__(self, key): 647 # # del self.emplyee[key] # 删除emplyee属性中的某个元素 648 # def __str__(self): # 定制对象的字符串形式,方式1,(str,print函数) 649 # return "公司名称为:%s,boss是%s"%(self.name,self.boss) 650 # def __repr__(self): 651 # return self.name 652 # 653 # shu_guo = Company("蜀国","刘备",["张飞","关羽","赵云","诸葛亮"]) 654 # # print(shu_guo[0]) # --> __getitem__ 655 # # print(shu_guo[:]) # --> __getitem__ 656 # # shu_guo[0] = "张三" # --> __setitem__ 657 # # print(shu_guo[:]) 658 # # shu_guo[0:2] = ["张飞","关云长"] 659 # # print(shu_guo[:]) 660 # # del shu_guo[3] # --> __delitem__ 661 # # print(shu_guo[:]) 662 # # # print(shu_guo) # 内存地址 <__main__.Company object at 0x000002B6C3A783C8> 663 # # print(shu_guo) # 蜀国 664 # # print(str(shu_guo)) # 蜀国 665 # # print(repr(shu_guo)) # <__main__.Company object at 0x000002339FFB8978> 666 # print(shu_guo) 667 # print(str(shu_guo)) 668 # print(repr(shu_guo)) 669 670 # class Cat: 671 # legs = 4 672 # def __init__(self,name): 673 # self.name = name 674 # def __say(self): 675 # print("小猫喵喵喵") 676 # def get__say(self): 677 # self.__say() 678 # 679 # # tom = Cat("汤姆") 680 # # jerry = Cat("杰瑞") 681 # # print(tom.legs) 682 # # print(jerry.legs) 683 # # print(Cat.legs) 684 # # Cat.legs = 5 685 # # print(tom.legs) 686 # # print(jerry.legs) 687 # # print(Cat.legs) 688 # # tom.legs = 3 689 # # print(tom.legs) 690 # # print(jerry.legs) 691 # # print(Cat.legs) 692 # class SmallCat(Cat): 693 # def __init__(self,name,age): 694 # super(SmallCat,self).__init__(name) 695 # self.age = age 696 # 697 # tom = SmallCat("汤姆",1) 698 # tom.get__say()