面向对象的概念
面向对象:一种编程思想,类、对象
类:具有同一特征的事物,抽象的,不是真实存在的事物
类可以创建对象,由对象创建;一个类创建多个对象
对象:类可以创建对象
类的属性:特征
类的方法:行为
面向对象结构
class WashingMachine:
heiht = 850 # 属性
width = 460
# 方法
def laundry(self): #类创建出来的对象
print('洗衣服')
haier = WashingMachine() # 对象
haier.colour = 'red' # 类外创建属性
haier.heiht = 800 # 类外可以改变属性值,但是还有其他对象,如格力等,只因为一个而改变全部洗衣机的参数不合适,定义实例属性
haier.laundry()
print(haier.colour)
# print(haier.width) # 这是某一个对象,但是类本身没有变化
魔法方法
class Hero: # 对象创建先new定义一个类型,然后初始化传参
def __str__(self): # 直接打印的时候方便一点
return '面对疾风吧!'
def __init__(self, str_data): # 初始化魔法方法,创建对象自动运行
self.h = 1888 # 初始化定义属性是实例属性,针对每个实例,定义只能实例调用如yx.data
self.data = str_data # 类的属性是公共属性,不仅可以实例调用,还可以类调用,如Hero.data
def __call__(self,canshu): # call可以让类方法像函数一样赋值调用 如可以yx(3)之类的
def __add__(self, other): # 魔法方法内置函数,就像触发这个加法是见到+号
return self.data + other # 而自定义方法只能Hero.add(),所以不一样
# 只是触发条件运行这个函数,至于返回什么自己定义
def __rsub__(self, other): # 可以定义左右运算,运算符的位置
return other-self.data
def __del__(self):
print('以删除') # 对象创立之后自动删除,防止占用内存
yx = Hero(3)
print(yx)
print(yx.h)
print(yx+3+3) # add
print(2-yx)
类的继承
class F(object):
money = 100
class S(F):
def __init__(self):
print(self.money)
S()
输出结果:
100 # 子类继承了父类的属性
多继承
子类可以继承多个父类,多个父类含有相同参数,按照继承层级继承,继承父类的顺序即继承层级
可以用S.__mro__
获取继承的层级
class F:
money = 1000000
class M:
money = 100
house = '十套房'
class S(F, M):
pass
print(S.money)
print(S.__mro__) # 获取继承层级
子类重写父类
子类可以重写父类属性与函数
class F:
money = 100
def like(self):
print('喜欢钓鱼')
class S(F):
money = 1000000
def like(self): # 方法重写
print('喜欢游戏')
s = S()
s.like()
print(s.money)
输出结果:# 按照子类自己的结果
喜欢游戏
1000000
子类__init__函数实例化对象调用父类的函数
class F:
money = 100
def like(self):
print('喜欢钓鱼')
class S(F):
def __init__(self):
print(f'f的money为{self.money}')
self.like()
s = S()
调用父类的__init__初始化对象
子类没有初始化对象,默认使用父类的init
子类继承父类的参数时,多个参数,需要用super().__init__(say_data)
写明传入多个参数,哪个是父类的,哪个是子类的
class F:
def __init__(self, data):
self.data = data
def say(self):
print(f'说了:{self.data}')
class S(F):
# 当没有写init初始化的时候,默认使用父类的init
def __init__(self, game, say_data):
super().__init__(say_data)
self.game = game
def like(self):
print(f'喜欢打{self.game}游戏')
s = S('象棋','你好!')
s.say()
s.like()
单例模式
单例模式:一个类只能有一个实例,且该类能自行创建这个模式的一种模式。如windows只能打开一个任务管理器
单例类只有一个实例对象;该单例类由单例对象自行创建;单例类对外提供一个访问该单例的全局访问点
每一次生成的实例对象内存地址是相同的
__new__是由object基类提供的内置静态方法,为对象分配空间,__init__在生成实例时自动执行
单例模式
- 重写__new__函数
class player():
_instance = None # 创建一个静态变量,_instance表示当前地址
_flag = None # init还是执行两次,为了使init执行一次
def __new__(cls,*args, **kwargs): # cls代表类
print('新的new函数')
if cls.__instance is None: # 如果当前类的内存地址为空,则调用父类的new方法,和父类保持相同的地址
cls.__instance = super().__new__(cls, *args, **kwargs)
# 可以在这里给实力对象绑定一些固有属性
# cls.__instance.appkey = ""
return cls.__instance
def __init__(self): # self是对象本身
if not player._flag:
print('init运行')
player.__flag = True
video = player() # 没有init函数,打印出来的都是不同的内存地址
music = player()
上面的函数等同于:
class Singleton(object):
def __new__(cls, *args, **kwargs):
# 判断是否存在类属性_instance,_instance是类CCP的唯一对象,即单例
if not hasattr(Singleton, "__instance"):
cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
# cls.__instance = object.__new__(cls)
return cls.__instance
借用hasattr
函数,hasattr(cls, name)
用于判断cls类中是否包含name对象或者方法