zl程序教程

您现在的位置是:首页 >  Python

当前栏目

Python面向对象编程(OOP) —— 继承、使用槽

2023-04-18 14:55:48 时间

另一个关于OOP的概念是"继承",在一个类的基础上,"继承" 其方法和属性,构建另外一个类。

目录

一、为什么会有"继承" 这个概念?

1.1、在多个类中继承

二、更好的控制对象 —— 使用槽

2.1、我们指定Python 保存的类型

一、为什么会有"继承" 这个概念?

一张图看懂"继承"

class 父类:

    def 父类中的方法(self):
        #做事情

class 子类(父类): #子类继承父类,子类拥有父类的所有方法
     .....


zi = 子类() 创建子类对象,也就是创建一个子类实例
zi.父类中的方法 #执行父类的方法

考虑一下许多相似而又有少数关键差别的数据类型,你可能会想到用OOP处理这种数据。你可以为每个数据类型创建各不相同的类,但是会许多代码的重复,效率并不是很高

更好的方法是定义一个包含共同元素的"基类",然后定义从基类ji继承特性的"子类"。

假如你需要编写一个涉及不同类型交通工具的游戏或模拟程序,你希望为每种类型的交通工具定义各自的类,它们之间有什么属性?

交通工具共同点于不同:

1、所有的交通工具都在屏幕上有X和Y坐标及速度,所有交通工具也有共同的移动和渲染方法,就像前面我们用类来写弹球游戏的程序一样弹球游戏的两种编写方式,这些都可以放入 基类"Vehicle" 2、然后我们可以开始考虑特定交通工具的子类。例如,挖掘机需要"Vehicle"的所有功能,还得包括只有挖掘机才具备的特殊方法,比如挖掘机有铲子,它的功能就是"挖掘",还有直升机也必须基于"Vehicle"类,但是需要自己的"z_pow(高度)"才能离开地面 看下面这段代码:

class Vehicle:
    def __init__(self,x,y):
        self.x_pos =x
        self.y_pos =y
        self.x_speed = 0
        self.y_speed = 0

    def update(self):
        print("Moving...")
        self.x_pos +=self.x_speed
        self.y_pos +=self.y_speed

    def render(self):
        print("Drawing...")


class Digger(Vehicle): #挖掘机从 基类"Vehicle" 继承方法和属性
    def __init__(self,x,y):
        Vehicle.__init__(self,x,y) #首先初始化"Vehicle"部分

    def dig(self):#增加挖掘机特有的类的方法
        print("Digging...")


class Helicopter(Vehicle):
    def __init__(self,x,y,height):
        Vehicle.__init__(self,x,y)
        self.z_pow = height #直升机特有的属性

car = Vehicle(10,20)
car.update()
car.render()

digger = Digger(50,90)
digger.dig()#只有 挖掘机才能调用此方法

chopper = Helicopter(200,400,50)
chopper.update()
chopper.render()

1.1、在多个类中继承

 这个程序很清晰的向我们展示了如何从另一个类中继承方法和属性,但是我们还可以从多个类中继承,只需要在类定义中的括号,放入多个基类,然后用逗号分隔开,但是一般er 议这么做

二、更好的控制对象 —— 使用槽

更好的控制对象,准确的来说,是控制它们拥有的属性。举个例子,当你创建对象时,可以在程序中添加额外的属性,即使这些属性并不在类定义中,先看看下面这个实例程序

class Myclass:
    def __init__(self,passed_number):
        self.number = passed_number


x = Myclass(10)
print(x.number)

x.text = "Hello,everybody"
print(x.text)

print(x.__dict__)

这里我们创建了一个新的类定义,包含属性 "number",当我们创建 x = Myclass(10) 这个实例时,将其属性设置为10。一切顺利,到了后面 x.text = “Hello,everybody” 又是什么鬼,这里我们创立了一个新属性 —— 字符串属性,在类定义没有规定它。

尽管我们创建了一个新属性,但是缺点也很明显,属性保存在字典当中,需要花时间处理,内存的利用也并不是很有效,出现这种现象的特有字典也就是我们打印的 "__dict__“,第三行的运行结果也显示出字典的内容

2.1、我们指定Python 保存的类型

为了节省空间,我们可以指定Python不用字典保存实例属性。你可以指定允许创建哪些属性,这样就不会创建任何其它的属性,这种功能可以通过"槽" (slot)实现,具体看下面这段代码

class Myclass(object):
    __slots__ = ["number","name"]
    def __init__(self,passed_number):
        self.number = passed_number


x = Myclass(10)
print(x.number)

x.name = "Bob"
print(x.name)

x.text = "Hello"

10 和"Bob" 正常的打印出来了,但是程序报错告诉我们,我们没有定义 "text" 这个属性。其实我要说的不在这里

当我们要处理的数据量非常庞大的时候,然而用字典存储数据是非常浪费的,我们就可以通过"__slot__" 更j们要存储的数据,这样就可以极大的节省内存