什么是继承?
软件重用的重要方式:1、继承,2、组合
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性,抽象类是一个介于类和接口之间的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
python中支持多继承(不推荐使用多继承)
1、什么是继承?
就是让子类拥有父类的属性和方法,python所有的类都是直接或者间接继承object
2、怎么继承?
class 类名(父类):
3、能继承哪些东西?
对象属性、对象方法、类属性、类方法、静态方法都可以继承
注意:如果设置了slots的值,会约束当前类的对象属性,并且会影响当前类对象的dict不存在
slots的值不会约束到子类对象的属性,但是会导致子类对象的dict只有当前类添加的属性
2、继承父类,发展自身
(1)改变:重写方法
(2)拓展:创建新方法、新属性
(3)super()--返回父类或父类对象:在子类中通过super().方法去保留父类的方法
3、类中函数调用过程:先找当前类是否有此方法,若有就调用,若没有就找父类,以此类推,直到object
4、添加属性:
(1)字段:直接在子类中添加字段
(2)属性:通过init方法设置
当子类没有申明init方法的时候,自动调用父类的init方法
当子类有init方法的时候,需要在内部调用父类的init方法来继承父类的属性,不然被复写
class Person:
def __init__(self,name,age=0,id=''):
self.name=name
self.age=age
self.id=id
def show_info(self):
print(self.__dict__)
class Student(Person):
def __init__(self,stuID,name='',age=0):
self.stuid=stuID
super().__init__(name,age)
self.score=0
p1=Person("xiaowang ")
p1.show_info()
p2=Person("xiaoming",22)
p2.show_info()
p3=Person("xiaozhang",22,123123)
p3.show_info()
stu1=Student("stu001")
stu1.show_info()
class Car:
def __init__(self,name,color="black"):
self.name=name
self.color=color
@staticmethod
def run( ):
print("car is runing")
class SportCar(Car):
def __init__(self,name):
super().__init__(name)
@staticmethod
def run():
print("sport car is runing")
class Truck(Car):
def __init__(self,name,color="blue"):
super().__init__(name,color)
@staticmethod
def run():
print("sport car is runing")
car1=SportCar('aaa')
car2=Truck("bbb")
car3=Truck('ccc','yellow')
print(car1.color)
print(car2.color)
print(car3.color)
运算符重载
运算符重载:通过实现类相关的魔法方法,来让类支持相应的运算符
import copy
import random
class Student:
names=["Jame","Amy","Koke","Torres","salash","messi",'zaha','hazard','ozil','macerlo','Toni']
def __init__(self,name='',age=''):
self.name=name
self.age=age
#__gt__()是>符号的魔法方法
def __gt__(self, other):
#self大于符号前面的值,other大于符号后面的值
return (self.age>other.age)
#*的魔法方法
def __mul__(self, other:int):
result=[]
for i in range(other):
self.name=Student.names[random.randint(0,10)]
self.age=random.randint(1,101)
result.append(copy.copy(self)) #若不用副本,则所有对象地址将一样
return result
def __repr__(self):
return str(self.__dict__)
stu1=Student('xiaoming',22)
stu2=Student("xiaohuang",25)
print(stu1<stu2)
stu=Student()*10
print(stu)
内存管理机制
1、栈区间:栈里面的空间是系统自动创建自动回收的
2、堆区间:手动开启,手动释放
目前大部分的编程语言都提供了一套关于堆区间的内存管理机制
python中的垃圾回收机制用来管理堆中内存的释放
python中的数据都是存在堆中的,数据对应的地址存放在栈里面
内存的开辟:
python中将值赋给变量,会先在堆中开辟空间将数据存起来,然后将数据对应的地址返回给变量存在栈中
但是如果数据是数字或字符串,会先在缓存区中查看这个数据是否已经创建,若已经创建则返回已有地址
若没有创建则开辟新空间,返回地址;
内存的释放:垃圾回收机制
系统没隔一定的时间就会去检查当前程序中所有的对象的引用计数值是否是零;
如果对象的引用计数是0,对象指向的内存就会被销毁
每一个对象都有引用计数属性,用来存储当前对象被引用的次数,可通过sys模块getrefcount获取
减少引用计数:删除引用对象的地址;修改变量
from sys import getrefcount
a=[1,2]
b=[1,2]
print(id(a),id(b))
c=100
d=100
print(id(c),id(d))
aaa=[1,2,3]
print(getrefcount(aaa))
print(getrefcount(aaa))
bbb=1
print(getrefcount(bbb))
网友评论