'''
继承:
1、类方法、静态方法、私有属性
类方法:使用装饰器@classmethod,第一个参数必须是当前类的对象,该参数名一般约定为"cls",
通过它来传递类的属性和方法(不能传实例的属性和方法),"cls"代表类本身
类方法调用:实例对象和类对象都可以调用
实例方法:只能由实例对象来调用
应用场景:需要站在类的角度执行某个行为时,那么就应该定义为类方法
静态方法(了解即可):
定义:使用装饰器@staticmethod,参数随意,没有"self"和"cls"参数,
但是方法体中不能使用类或者实例的任何属性和方法
调用:实例对象和类对象都可以调用
应用场景:存放逻辑代码,内部不需要引用类属性和实例属性
私有属性(了解即可):
单下划线开头:_attr
双下滑开头:__attr
声明为私有属性:声明为私有属性,那么该说明属性是类私有的,仅限于在类里面使用,
不要在类外面去调用(实际上类外面可以访问,讨论这个毫无意义)
2、类的继承关系
什么是继承,继承有什么作用?
面向对象编程中有一个重要的思想叫继承,子类通过继承可以获得父类的属性和方法,
被继承的类叫做父类(基类),继承的类叫子类
作用:子类通过继承可以获得父类的属性和方法,提高开发的效率及代码的复用率
类的两种定义方式:
方式一:
class 类名:
pass
方式二:
class 类名(继承的父类):
pass
object:是所有类的顶级父类(基类)
类属性可以直接继承
实例方法通过继承可以得到
实例属性能不能继承?
实例属性是每个实例对象所独自有的,不是通过继承得到的
继承是针对类而言的,只有类里面的东西才能被继承
创建实例对象的时候才会进行赋值
将有限的时间和精力花在当前我们紧急要做的事情上面
在最短的时间用python去做自动化,而不是研究底层原理和高阶编程
3、重写父类方法
重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖父类中同名的方法
直接调用重写之后的方法,直接调用自身有的这个方法(不会去父类找)
在方法中调父类被重写的方法:
方式一:父类名.方法名
方式二:super().方法名()
扩展:
___new__方法:创建对象
Create and return a new object
面向对象的三大特征:
继承:
封装:将变量定为类属性和相似功能的函数(方法)进行封装
多态:鸭子类型
4、调用重名的父类方法
子类重写了父类的方法之后,如何在子类中再调用父类的方法?
方式一:父类.方法名(self)
方式二:super().方法名()
5、属性动态设置(反射机制)
setattr:设置属性
getattr:获取属性
delattr:删除属性
总结:
万物皆对象
函数:函数对象
基本数据:str list
类:类对象
模块(文件):模块对象
包:包对象
自定义类创建出来的对象
'''
"""
特征(属性):血量(HP) 蓝量(XP) 攻击力(attack) 暴击率
行为(方法):技能1 技能2 技能3 移动
总结:类的定义、属性、方法,self的含义,初始化方法
问题需求:
需求V1:实现一个初始版的手机类(大哥大)
只能打电话
需求V2:实现一个定义功能机类
打电话、听音乐、发短信
需求V3:实现一个智能手机类
打电话、听音乐、发短信、看视频、玩游戏、手机支付、视频通话
"""
class Hero:
def __init__(self,name,HP):
self.name = name
self.HP = HP
print("自动调用了---init---方法,完成实例对象的初始化")
def move(self):
print("走向战场")
def skill(self):
print("使用了技能砍一刀")
class MyClass:
# 定义类属性
attr = 100
# 私有属性(声明为私有属性之后,不要在类外面通过类或者对象去使用这个属性)
_attr = 999
__attr = 99999
# 定义实例属性
def __init__(self,name,age):
self.name = name
self.age = age
# 定义实例方法
def func1(self):
print("实例方法1")
# 定义类方法@classmethod
@classmethod
def c_func(cls):
print("类方法c_func")
# 静态方法,将函数定义到类里面来,可以定义为静态方法
@staticmethod
def s_func():
print("这个是静态方法")
# # 创建一个m对象,并给m对象赋值
m = MyClass("hc",18)
# # 调用实例方法(类无法调用实例方法,例如:MyClass.func1())
# m.func1()
#
# # 对象调用类方法
m.c_func()
# 类调用类方法
MyClass.c_func()
# 静态方法的调用
MyClass.s_func()
m.s_func()
# 类的两种定义方式:
# 如果不写继承的父类(默认也是继承于object)
class Myclass:
pass
# 可以自己指定继承的父类
class MyClassA(object):
pass
# 继承关系,举例
class BasePhone(object):
"""大哥大"""
# basephone手机的类属性
attr = "红色"
# 定义实例属性,是独有的,需要传参数
def __init__(self,name):
self.name = name
# 定义实例方法,不是独有的,无需传参
def call_phone(self):
print("打语音电话base")
# Phone_V1继承BasePhone所有功能
class Phone_V1(BasePhone):
# 功能机
def call_phone(self):
print("打语音电话v1")
def send_msg(self):
print("发短信功能")
def music(self):
print("听音乐")
class Phone_v2(Phone_V1):
"""智能机"""
# 重写父类的方法,更新和升级父类方法
# 父类有一个方法,继承之后定义了一个和父类方法名相同的方法
def call_phone(self):
print("拨打视频电话")
print("时间过去了5分钟再转成语音通话")
# 在方法中调用父类被重写的方法
# 方式一:类名.方法名(self)
# 通过类调用实例方法,self必须自己传参
BasePhone.call_phone(self)
# 方式二:super().方法名()
super().call_phone()
def game(self):
print("玩游戏")
def qq(self):
print("聊QQ")
xm = Phone_v2("华为P30")
# 访问继承的实例方法
xm.call_phone()
xm.send_msg()
xm.game()
# 调用父类的实例属性
print(xm.name)
# 访问继承的属性
print(Phone_v2.attr)
b1 = BasePhone("大哥大")
v1 = Phone_V1("oppo音乐手机")
p1 = Phone_v2("华为P30")
print(p1.name)
print(b1.name)
print(v1.name)
# 重写父类的call_phone方法后子类调用父类的方法
v2 = Phone_v2("华为P30")
# 直接调用重写之后的方法,直接调用自身有的这个方法(不会调用父类的方法)
v2.call_phone()
# 重写父类方法的应用场景
class Obj(object):
# 重写new方法
# 第一种调用new方法的方式,自己创建的new方法无法创建对象,需要借用父类的
def __new__(cls,*arg,**kwargs):
# object.__new__(cls)
# 第二种:
res = super().__new__(cls)
return res
# 通过类名创建对象,没有重写new方法,默认调用object类中的new方法
o = Obj()
print(o)
# 属性动态属性(反射机制):
class Cases:
def __init__(self,name):
self.name = name
case1 = Cases("111")
datas = {"case_id":1,"data":"999","url":"www.baidu.com"}
# 对象.属性名 = 属性值
# setattr:设置属性
# 给对象动态设置属性:参数(对象,属性名,属性值)
setattr(case1,"age",99) # 等同于:case1.age = 99
print(case1.age)
for k,v in datas.items():
print(k,v,type(k),type(v))
# case1.k = v
setattr(case1,k,v)
print(case1.url)
# getattr:获取属性
res = getattr(case1,"name")
print(res)
# delattr:删除属性
res = delattr(case1,"name")
print(res)