继承
定义:
子类可以重复父类成员,并可以在此基础上扩展。
法语:
class 子类(父类):
pass
继承方法:
子类可以调用父类的方法
注意:
兄弟类之间的方法不能互相调用。
内置函数:
isinstance(对象, 类型)
getattr(obj, name, default)
hasattr(obj, name)
继承数据:
语法:
class 子类(父类):
def __init__(self, 参数列表):
# 方法1:
父类名.__init__(self, 参数列表)
# 方法2:推荐
super().__init__(参数列表)
self.属性 = 数据
注意:
1、子类中存在与父类实例变量同名,覆盖父类中定义的实例变量
2、子类继承了父类,如果子类中无构造方法,直接调用父类的构造方法
总结:
特点:
如果子类继承了父类,则可以直接调用父类的方法
(继承方法、继承数据)
优点:
实现对代码的复用
缺点:
父类的变化可以直接影响子类(耦合度高)。
重写:
定义:
子类中实现了与父类中同名的方法。
目的:
对父类的方法扩展。
说明:
父类的方法不满足子类的需求时。
(父类的同名方法会被覆盖,不执行)
体现子类的个性。
内置的魔法方法:
__str__: [重点]
将对象转换为字符串(对人友好)
__repr__:
将对象转换为字符串(对机器友好)
内置函数:
eval(source) [重点]
将字符串作为表达式执行
运算符重载:
基本运算符
复合赋值运算符
比较运算符
__eq__
设计角度:
定义:
将相关类的共性抽象,统一概念,隔离变化点。
使用:
多个类在概念上是一致的,且需要统一处理。
相关概念:
1、父类也称为基类、超类,子类称为派生类。
2、父类相对于子类更加抽象,范围更加宽泛。
子类相对于父类更加具体,范围更加狭小。
3、单继承:只有一个父类。
python 3:默认为继承object
4、多继承:父类有多个。
2、多继承
概念:
一个类继承2个或2个以上的基类,父类的方法或属性都会被同时继承下来。
查看子类的继承链
子类名.mro()
继承顺序:
类自身 --> 父类继承列表(从左至右)--> 生层父类(从左至右)
# 继承数据
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
class BlueCat(Cat):
def __init__(self, sex):
# 方法1:
Cat.__init__(self, '加菲猫', 1)
self.sex = sex
# 需求:子类可以调用父类的实例变量
c01 = BlueCat('母')
print(c01.__dict__)
print(c01.name, c01.age)
c02 = BlueCat('公')
print(c02.__dict__)
print(c02.name, c02.age)
# 问题:不管实例出多个子类对象,它的name/age都是固定的(不灵活)
# 继承数据
# 问题:不管实例出多个子类对象,它的name/age都是固定的(不灵活)
# 方法:在子类中的构造方法中添加对应的参数
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
class BlueCat(Cat):
def __init__(self, name, age, sex):
# 方法1:不灵活
# Cats.__init__(self, name, age)
# 方法2:
# print(super())
super().__init__(name, age)
# 不会生成父类对象,仅是为子类对象添加对应的属性
self.sex = sex
# 需求:子类可以调用父类的实例变量
c01 = BlueCat('加菲', 2, '母')
print(c01.__dict__)
print(c01.name, c01.age)
c02 = BlueCat('蓝猫', 1, '公')
print(c02.__dict__)
print(c02.name, c02.age)
# 继承数据
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
class BlueCat(Cat):
def __init__(self, name, age, sex):
super().__init__(name, age)
print('类内:', self.__dict__)
self.age = age # 覆盖父类中定义的属性(不推荐)
self.sex = sex
# 需求:子类可以调用父类的实例变量
c01 = BlueCat('加菲', 2, '母')
print(c01.__dict__)
print(c01.name, c01.age)
# 继承数据
class Fruit:
def __init__(self, name, price):
self.name = name
self.price = price
class Apple(Fruit):
def infos(self):
print('这是apple类')
print(self.name, self.price)
# 子类继承了父类,如果子类中无构造方法,直接调用父类的构造方法
a01 = Apple('苹果', 15)
print(a01.name)
a01.infos()
# 定义父类:车
# 数据:品牌、价格
# 行为:行驶
#
# 定义子类:比亚迪
# 数据:颜色、速度
# 行为:行驶(保持父类的行驶行为,同时打印出:
# ‘xxx品牌的车颜色:xx, 价格:xxx, 速度:xxx’)
class Car:
def __init__(self, brand, price):
self.brand = brand
self.price = price
def run(self):
print('dididi')
class BYD(Car):
def __init__(self, brand, price, color, speed):
super().__init__(brand, price)
self.color = color
self.speed = speed
def run(self):
# 调用父类的方法
# self.run() 调用自身
super().run()
print('{}的车颜色是:{},价格是:{},速度是:{}'.format(
self.brand, self.color, self.price, self.speed
))
byd = BYD('比亚迪', 128888, '红色', 120)
byd.run()
# 问题:调用的是子类/父类的run方法 (子)
# 说明:如果子类继承了父类,则可以直接调用父类的方法
# 重写
class Wife(object):
def __init__(self, name='', age=0):
self.name = name
self.age = age
def __str__(self): # 重写【对人友好】
return f'{self.name}-{self.age}'
def __repr__(self): # 重写【对机器友好】
return 'Wife("%s", "%d")' % (self.name, self.age)
w01 = Wife('高圆圆', 22)
print(w01) # 默认返回对象在计算机中的内存地址
# print(w01.__str__())
print(w01.__repr__())
print(type(w01.__repr__()))
# 函数:eval(source) # 将字符串作为表达式执行
res = w01.__repr__()
print(eval(res))
print('-' * 50)
res1 = eval('1+2+3+4+5.5')
print(res1, type(res1))
print(list('[5, 6, 78, 9]'))
print(eval('[5, 6, 78, 9]'))
# data = input('亲输入一个年份:')
# print(data, type(data))
#
# data = eval(input('亲输入一个年份:'))
# print(data, type(data))
# 运算符重载
# s1 = 'hello '
# s2 = 'word'
# print(s1 + s2)
#
# s1 += s2
# print(s1)
class Vector2:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return 'x={},y={}'.format(self.x, self.y)
def __add__(self, other): # +
return Vector2(self.x+other.x, self.y+other.y)
def __iadd__(self, other): # +=
self.x += other.x
self.y += other.y
return self
def __gt__(self, other): # >
return self.x > other.x and self.y > other.y
def __lt__(self, other):
return self.x < other.x
def __eq__(self, other):
return self.x == other.x and self.y == other.y
v01 = Vector2(1,1)
print(v01)
v02 = Vector2(2,5)
print(v01.x + v02.x)
print(v01.y + v02.y)
# print(v01 + v02) # 调用__add__方法
v01 += v02 # 调用__iadd__方法
print('v01=', v01)
res2 = v01 > v02 # 调用__gt__方法
print('>', res2)
list_vector = [
Vector2(1, 4),
Vector2(5, 1),
Vector2(2, 2),
Vector2(4, 5),
]
# 排序
list_vector.sort() # 默认调用 __lt__
print(list_vector)
for item in list_vector:
print(item)
# in # 调用 __eq__
print(Vector2(5, 1) in list_vector)
print(list_vector.count(Vector2(2, 2)))
print(list_vector.remove(Vector2(2, 2)))
def __add__(obj1, obj2): # 不推荐
print(obj1.x+obj2.x, obj1.y+obj2.y)
__add__(v01, v02)
print(v01 + v02)