社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
在使用面相对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类!
在程序开发中,要设计一个类,通常需要满足以下三个要素:
CapWords
名词提炼法 分析 整个业务流程,出现的 名词,通常就是找到的类
提示:需求中没有涉及的属性或者方法在设计类时,不需要考虑
需求
需求
面向对象 是 更大 的 封装,在 一个类中 封装 多个方法,这样 通过这个类创建出来的对象,就可以直接调用这些方法了!
Python
中要定义一个只包含方法的类,语法格式如下:class 类名:
def 方法1(self, 参数列表):
pass
def 方法2(self, 参数列表):
pass
self
,大家暂时先记住,稍后介绍 self
注意:类名 的 命名规则 要符合 大驼峰命名法
对象变量 = 类名()
需求
分析
Cat
eat
和 drink
class Cat:
"""这是一个猫类"""
def eat(self):
print("小猫爱吃鱼")
def drink(self):
print("小猫在喝水")
tom = Cat()
tom.drink()
tom.eat()
输出:
self
参数Python
中,要 给对象设置属性,非常的容易,但是不推荐使用
.
设置一个属性即可注意:这种方式虽然简单,但是不推荐使用!
tom.name = "Tom"
...
lazy_cat.name = "大懒猫"
self
在方法内部输出每一只猫的名字由 哪一个对象 调用的方法,方法内的
self
就是 哪一个对象的引用
self
就表示 当前调用方法的对象自己self
参数self.
访问对象的属性self.
调用其他的对象方法class Cat:
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat()
tom.name = "Tom"
tom.eat()
lazy_cat = Cat()
lazy_cat.name = "大懒猫"
lazy_cat.eat()
输出:
Tom 爱吃鱼
大懒猫 爱吃鱼
变量名.
访问对象的 属性和方法self.
访问对象的 属性和方法类名()
创建对象时,会 自动 执行以下操作:
init
)__init__
方法,__init__
是对象的内置方法
__init__
方法是 专门 用来定义一个类 具有哪些属性的方法!
在 Cat
中增加 __init__
方法,该方法在创建对象时会被自动调用
class Cat:
"""这是一个猫类"""
def __init__(self):
print("初始化方法")
__init__
方法内部使用 self.属性名 = 属性的初始值
就可以 定义属性Cat
类创建的对象,都会拥有该属性class Cat:
def __init__(self):
print("这是一个初始化方法")
# 定义用 Cat 类创建的猫对象都有一个 name 的属性
self.name = "Tom"
def eat(self):
print("%s 爱吃鱼" % self.name)
# 使用类名()创建对象的时候,会自动调用初始化方法 __init__
tom = Cat()
tom.eat()
输出:
__init__
方法进行 改造
__init__
方法的参数self.属性 = 形参
接收外部传递的参数。【只有需要从外部传入的参数,才需要把这些参数定义成初始化方法的形参,如果某些参数不需要外部传递,就不需要额外增加那些参数,直接 self.属性 = 设定的某初始值
】类名(属性1, 属性2...)
调用class Cat:
def __init__(self, name):
print("初始化方法 %s" % name)
self.name = name
...
tom = Cat("Tom")
...
lazy_cat = Cat("大懒猫")
...
定义没有初始值的属性
在定义属性时,如果 不知道设置什么初始值,可以设置为 None
None
关键字 表示 什么都没有None
赋值给任何一个变量一个对象的 属性 可以是 另外一个类创建的对象:
class Gun:
def __init__(self, model):
self.model = model
self.bullet_count = 0
def add_bullet(self, count):
self.bullet_count += count
def shoot(self):
if self.bullet_count <= 0:
print("[%s] 没有子弹了..." % self.model)
return
self.bullet_count -= 1
print("[%s] 突突突... [%d]" % (self.model, self.bullet_count))
class Soldier:
def __init__(self, name):
self.name = name
self.gun = None
def fire(self):
if self.gun == None:
print("[%s] 还没有枪..." % self.name)
return
print("冲啊...[%s]" % self.name)
self.gun.add_bullet(50)
self.gun.shoot()
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __del__ | 方法 | 对象被从内存中销毁前,会被 自动 调用 |
02 | __str__ | 方法 | 返回对象的描述信息,print 函数输出使用 |
__del__
方法(知道)在 Python
中
类名()
创建对象时,为对象 分配完空间后,自动 调用 __init__
方法__del__
方法应用场景
__init__
改造初始化方法,可以让创建对象更加灵活__del__
如果希望在对象被销毁前,再做一些事情,可以考虑一下 __del__
方法生命周期
类名()
创建,生命周期开始__del__
方法一旦被调用,生命周期结束class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
# tom 是一个全局变量
tom = Cat("Tom")
print(tom.name)
# del 关键字可以删除一个对象
del tom
print("-" * 50)
输出为:
__str__
方法(☆☆☆重要)Python
中,使用 print
输出 对象变量,默认情况下,会输出这个变量 引用的对象 是 由哪一个类创建的对象,以及 在内存中的地址(十六进制表示)print
输出 对象变量 时,能够打印 自定义的内容,就可以利用 __str__
这个内置方法了注意:
__str__
方法必须返回一个字符串
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
def __str__(self):
return "我是小猫[%s]" % self.name
tom = Cat("Tom")
print(tom)
输出为:
身份运算符用于 比较 两个对象的 内存地址 是否一致 —— 是否是对同一个对象的引用
Python
中针对 None
比较时,建议使用 is
判断运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用同一个对象 | x is y,类似 id(x) == id(y) |
is not | is not 是判断两个标识符是不是引用不同对象 | x is not y,类似 id(a) != id(b) |
is
用于判断 两个变量 引用对象是否为同一个==
用于判断 引用变量的值 是否相等
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> b is a
False
>>> b == a
True
应用场景
定义方式
class Women:
def __init__(self, name):
self.name = name
# 不要问女生的年龄
self.__age = 18
def __secret(self):
print("我的年龄是 %d" % self.__age)
xiaofang = Women("小芳")
# 私有属性,外部不能直接访问
# print(xiaofang.__age)
# 私有方法,外部不能直接调用
# xiaofang.__secret()
在对象的内部,是可以访问对象的私有属性和方法的;在对象的外部,不能访问对象的私有属性和方法!!!
运行结果:
小芳 的年龄是 18
提示:在日常开发中,不要使用这种方式,访问对象的 私有属性 或 私有方法
Python
中,并没有 真正意义 的 私有
_类名
=> _类名__名称
# 私有属性,外部不能直接访问到,但可以通过"_类名__名称"来访问
print(xiaofang._Women__age)
# 私有方法,外部不能直接调用,但可以通过"_类名__名称"来访问
xiaofang._Women__secret()
输出为:
18
小芳 的年龄是 18
面向对象三大特性
继承的概念:子类 拥有 父类 的所有 方法 和 属性
class 类名(父类名):
pass
Dog
类是 Animal
类的子类,Animal
类是 Dog
类的父类,Dog
类从 Animal
类继承Dog
类是 Animal
类的派生类,Animal
类是 Dog
类的基类,Dog
类从 Animal
类派生C
类从 B
类继承,B
类又从 A
类继承C
类就具有 B
类和 A
类的所有属性和方法子类 拥有 父类 以及 父类的父类 中封装的所有 属性 和 方法
应用场景
重写 父类方法有两种情况:
具体的实现方式,就相当于在 子类中 定义了一个 和父类同名的方法并且实现
重写之后,在运行时,只会调用 子类中重写的方法,而不再会调用 父类封装的方法
super().父类方法
来调用父类方法的执行super
Python
中 super
是一个 特殊的类super()
就是使用 super
类创建出来的对象概念
语法
class 子类名(父类名1, 父类名2...)
pass
问题的提出
提示:开发时,应该尽量避免这种容易产生混淆的情况! —— 如果 父类之间 存在 同名的属性或者方法,应该 尽量避免 使用多继承
Python
中针对 类 提供了一个 内置属性 __mro__
可以查看 方法 搜索顺序method resolution order
,主要用于 在多继承时判断 方法、属性 的调用 路径print(C.__mro__)
输出结果
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
__mro__
的输出结果 从左至右 的顺序查找的
object
是Python
为所有对象提供的 基类,提供有一些内置的属性和方法,可以使用dir
函数查看
新式类:以 object
为基类的类,推荐使用
经典类:不以 object
为基类的类,不推荐使用
在 Python 3.x
中定义类时,如果没有指定父类,会 默认使用 object
作为该类的 基类 —— Python 3.x
中定义的类都是 新式类
在 Python 2.x
中定义类时,如果没有指定父类,则不会以 object
作为 基类
新式类 和 经典类 在多继承时 —— 会影响到方法的搜索顺序
为了保证编写的代码能够同时在 Python 2.x
和 Python 3.x
运行!
今后在定义类时,如果没有父类,建议统一继承自 object
class 类名(object):
pass
面向对象三大特性
需求
Dog
类中封装方法 game
XiaoTianDog
继承自 Dog
,并且重写 game
方法
Person
类,并且封装一个 和狗玩 的方法
game
方法案例小结
Person
类中只需要让 狗对象 调用 game
方法,而不关心具体是 什么狗
game
方法是在 Dog
父类中定义的多态 更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!
class Dog(object):
def __init__(self, name):
self.name = name
def game(self):
print("%s 蹦蹦跳跳的玩耍..." % self.name)
class XiaoTianDog(Dog):
def game(self):
print("%s 飞到天上去玩耍..." % self.name)
class Person(object):
def __init__(self, name):
self.name = name
def game_with_dog(self, dog):
print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name))
# 让狗玩耍
dog.game()
# 1. 创建一个狗对象
# wangcai = Dog("旺财")
wangcai = XiaoTianDog("飞天旺财")
# 2. 创建一个小明对象
xiaoming = Person("小明")
# 3. 让小明调用和狗玩的方法
xiaoming.game_with_dog(wangcai)
输出结果为:
__init__
为 对象初始化因此,通常也会把:
在程序执行时:
self.
结论
Python
中 一切皆对象:
class AAA:
定义的类属于 类对象obj1 = AAA()
属于 实例对象
Python
中,类 是一个特殊的对象 —— 类对象示例需求
name
class Tool(object):
# 使用赋值语句,定义类属性,记录创建工具对象的总数
count = 0
def __init__(self, name):
self.name = name
# 针对类属性做一个计数+1
Tool.count += 1
# 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")
tool3 = Tool("铁锹")
# 知道使用 Tool 类到底创建了多少个对象?
print("现在创建了 %d 个工具" % Tool.count)
Python
中 属性的获取 存在一个 向上查找机制注意
对象.类属性 = 值
赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值class
关键字下方可以定义 类属性语法如下
@classmethod
def 类方法名(cls):
pass
@classmethod
来标识,告诉解释器这是一个类方法cls
cls
就是 哪一个类的引用如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!