. 面向对象 (OOP)
面向过程: 顺序执行, 只有执行, 没有返回值, 特点是侧重怎么做, 就是在主程序中调用不同的函数, 注重步骤和过程, 不负责责任分工, 不适合复杂项目的开发., 不适合新需求的增加
面向对象: 侧重于做事情的主体 (谁来做) 面向对象是更大的封装, 封装内容为方法. 即不同对象封装不同方法完成不同功能, 很适合于大型和复杂项目的开发.
核心概念: 类和对象, 类是抽象的不能直接使用, 其使命就是用来创造对象, 对象是类的实例化. 在程序开发中, 现有类, 再有对象. 类只需要有一个, 对象有多个, 不同对象之间属性可能各不相同. 类中有什么样的属性和方法, 对象就有什么样的属性和方法.
类的设计:(1)需求分析(== 类名, 属性和方法 == 且满足大驼峰命名法), 特征描述为属性, 行为描述为方法
一个内置函数 dir: 在 dir 中传入标识符 / 数据可查看所有属性和方法, 方法名为 python 提供的内置方法 / 属性
- >>> s = [1,2]
- >>> s
- [1, 2]
- >>> dir(s)
- ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
- >>>
定义简单的类(只包含方法):
- # 需求: 小猫爱吃鱼, 小猫爱喝水
- class Cat:
- def eat(self):
- print("小猫爱吃鱼儿")
- def drink(self):
- print("小猫爱喝水")
- # 实例化对象
- tom = Cat()
- tom.eat()
- tom.drink()
面向对象中的应用: 使用 print 输出对象变量默认情况下, 能够输出这个变量引用的对象是由哪一个类创建的以及在内存中的地址(以十六进制的形式表示)
- print(tom)
- <__main__.Cat object at 0x000001CEDA2B2B70>
初始化方法: 不推荐在类的外部增加属性
在类的外部增加属性(实例增加的是名字属性)
- # 需求: 小猫爱吃鱼, 小猫爱喝水
- class Cat:
- def eat(self):
- print("%s 爱吃鱼儿" % self.name)
- def drink(self):
- print("小猫爱喝水")
- # 实例化对象
- tom = Cat()
- tom.name = "tome"
- tom.eat()
- tom.drink()
- print(tom)
tome 爱吃鱼儿
小猫爱喝水
初始化方法(--init-- 是内置方法), 构造方法
作用: 定义类包含的属性
- class Cat:
- def __init__(self):
- print("this is a init way Sun easy")
- self.name = "Tom"
- tom = Cat() # 自动调用了初始化方法
- print(tom.name)
利用参数设置参数, 改造初始化方法
- class Cat:
- def __init__(self, new_name):
- print("this is a init way Sun easy")
- self.name = new_name
- def eat(self):
- print("%s like eat fish"%self.name)
- tom = Cat("Tome") # 自动调用了初始化方法
- print(tom.name)
- tom.eat()
--del-- 方法, 从内存中销毁的方法
当对象销毁的时候, 系统会对其自动销毁, 但是可以对其改造. del()可以删除对象
--str-- 方法
使用 print 打印查看自定义内容可以使用该函数
封装: 类的三大特性之一, 通过下列实例体会
- (摆家具实例)
- class HouseItem:
- def __init__(self, name, area):
- self.name = name
- self.area = area
- def __str__(self):
- return ("(%s) 占地 %.2f"% (self.name, self.area))
- class House:
- def __init__(self, hose_type, area):
- self.hose_type = hose_type
- self.area = area
- self.free_area = area
- self.item_list = []
- def __str__(self):
- return ("户型是:%s\n 总面积是:%.2f[剩余 %.2f]\n 家具有:%s" %
- ((self.hose_type, self.area, self.free_area, self.item_list)))
- def add_item(self, item):
- # 1. 判断家具面积是否小于房间面积
- print("要添加:%s" %item)
- if item.area> self.free_area:
- print("家具太大, 放不下")
- return
- # 2. 将家具名称添加至列表
- self.item_list.append(item.name)
- # 3. 计算剩余面积
- self.free_area = self.free_area - item.area
- bed = HouseItem("席梦思", 63)
- chest = HouseItem("衣柜", 2)
- table = HouseItem("餐桌", 1.5)
- print(bed)
- print(chest)
- print(table)
- print()
- my_home = House("两室一厅", 60)
- my_home.add_item(bed)
- my_home.add_item(chest)
- my_home.add_item(table)
- print(my_home)
运行结果:
(席梦思) 占地 63.00
(衣柜) 占地 2.00
(餐桌) 占地 1.50
要添加:(席梦思) 占地 63.00
家具太大, 放不下
要添加:(衣柜) 占地 2.00
要添加:(餐桌) 占地 1.50
户型是: 两室一厅
总面积是: 60.00[剩余 56.50]
家具有:['衣柜', '餐桌']
实例: 一个对象的属性可以是另外一个类的实例
- class Gun:
- def __init__(self, modle):
- self.model = modle
- self.bullet_count = 0
- def add_bullet(self,count):
- self.bullet_count = self.bullet_count + count
- def shoot(self):
- if self.bullet_count <= 0:
- print("没有子弹了.")
- return
- self.bullet_count -= 1
- print("%s 突突突》》》》》》[%d]"%(self.model, self.bullet_count))
- class Soldier:
- def __init__(self, name):
- self.gun = None
- self.name = name
- def fire(self):
- # 1. 判断是否有枪
- if self.gun == None:
- print("没有枪")
- # 2. 高喊口号
- print("冲啊")
- # 3. 发射子弹
- self.gun.add_bullet(50)
- self.gun.shoot()
- ak47 = Gun("ak47")
- xusanduo = Soldier("许三多")
- xusanduo.gun = ak47
- xusanduo.fire()
运行结果
冲啊
ak47 突突突》》》》》》[49]
== 身份运算符 ==is 用于判断是否为同一个对象(即地址是否相同)
私有属性和私有方法: 只希望在对象内部使用的属性和方法, 只需要增加两个下划线就可以, 注意: 这只是一种伪私有
- class Women:
- def __init__(self, name):
- self.name = name
- self.__age = 18
- def secret(self):
- print("%s 的年龄是 %d"%(self.name, self.__age))
- xiaofang = Women("小芳")
- # print(xiaofang.age) 私有属性不能够在外部访问
- # 可以通过这种方法强制使用
- print(xiaofang._Women__age)
- xiaofang.secret() # 对象方法内部可以直接使用
- 18
小芳 的年龄是 18
继承: 目的是实现代码重用, 子类拥有父类的所有属性和方法
继承之单继承
多态: 调用相同父类方法产生不同的执行结果, 可以增加代码灵活度
两个前提: 1 是继承 2 是需要重写父类的方法.
- class Dog(Animals): # 狗类继承自动物类
- print()
定义类方法 cls 修饰
- class Tools(object):
- count = 0 # 类属性是和类相关的机制
- @classmethod
- def show_to_count(cls):
- print("工具对象数目 %d"% cls.count)
- def __init__(self, name):
- self.name = name
- Tools.count += 1
- tool1 = Tools("斧头")
- tool2 = Tools("水桶")
- tool3 = Tools("马桶")
- print(tool1)
- print(tool2)
- print(Tools.count)
- print(tool2.count)
- print(tool1.count)
- # 调用类方法
- Tools.show_to_count()
运行结果
- <__main__.Tools object at 0x000001E0633B2D30>
- <__main__.Tools object at 0x000001E0633E2048>
- 3 3 3
工具对象数目 3
静态方法
- class Dog(object):
- @staticmethod
- def run():
- print("dog can run")
- Dog.run()
三种方法演练
- 静态方法: 显示游戏帮助信息
类方法: 显示历史最高分
实例方法: 开启当前玩家游戏
- class Game(object):
- # 类属性: 历史最高分
- top_score = 0
- def __init__(self,player_name):
- self.player_name = player_name
- @staticmethod
- def show_help():
- print("help message")
- @classmethod
- def show_top_score(cls):
- print("history score :%d" %cls.top_score)
- def start_game(self):
- print("%s game start" %self.player_name)
- # 1. 查看帮助信息
- Game.show_help()
- # 2. 查看历史最高峰
- Game.show_top_score()
- # 3. 创建对象
- game = Game("小明")
- game.start_game()
- help message
- history score :0
小明 game start
来源: http://www.jianshu.com/p/24a4ab38e0be