Skip to main content
 首页 » 编程设计

python之面向对象 : Trying to design a good class structure

2025年05月04日11yxwkf

跟进我发布的代码片段审查问题:https://codereview.stackexchange.com/questions/143576/oop-designing-class-inheritances

这是家庭作业,所以我不是要为我做,而是要为我澄清,以便我理解。

这是作业中关于我必须编写的程序的内容:

必需: 编写一个面向对象的 Python 程序,展示您的子类如何从父类(super class)继承您可以有一个类(首选但不是必须的)或两个或更多父类(super class)。

我要做的是编写一个 oo python 程序,显示一个类或两个或多个父类(super class)继承的子类。该程序必须是关于形状的。作为我的意思的一个例子是:

形状:正方形

属性:

  • 长度
  • 宽度

方法:

  • 地区
  • 周长

我当然有更多的形状,但从中我找到了所有形状的共同属性和方法,并创建了父类(super class)和父类(super class)。

我的父类(super class)是:2dShapes、圆圈和 3dShapes。我的子类就像长度和宽度。我的方法是面积和周长。请注意,我在这一点上漫无边际。下面的代码片段没有显示这一点,而是我在考虑为属性和方法创建父类(super class),而不是为形状创建子类?也许吧?

问题:这是一个好的类结构吗?有没有更好的方法来构造这里的类?这是我正在考虑如何执行此操作的示例。

class Shapes(attributes): 
    def __init__(self): 
        attributes.__init__(self) 
        # not sure how to go on to make the attributes like height and length, radius ect. Maybe like this??? 
    def height(self): 
        raise NotImplementedError # again this program is not supose to actually do anything. The program is just for us to understand inheritance with classes and super classes. 
 
class 2dShapes(Shapes): 
    class Square(self): 
        def height(self): 
            # ??? 

所以在这一点上,我对从哪里开始感到困惑。我也是 python 的 super 新手,所以对我温柔点:p

请您参考如下方法:

class Vehicle(object): 
    #class variable shared between all instances of objects.  
    number_of_vehicles = 0  
 
    def __init__(self,length,width,color,wheels): 
        self.length = length 
        self.width = width 
        self.color = color 
        self.wheels = wheels 
        Vehicle.number_of_vehicles += 1 #increasing class varaible count 
 
    def get_length(self): 
        print("I am %d meters long!"%self.length) 
 
    def get_wdith(self): 
        print("I am %d meters wide!"%self.width) 
 
    def get_color(self): 
        print("My color is %s!"%self.color) 
 
    def get_wheels(self): 
        print("I have %d number of wheels"%self.wheels) 
 
    #calling my methods so I don't need to call each of their own 
    def get_stats(self): 
        self.get_length() 
        self.get_wheels() 
        self.get_wdith() 
        self.get_color() 
 
    def honk(self): 
        print("beep beep") 
 
class Car(Vehicle): 
    def vroom(self): 
        print("Cars go vroom vroom") 
 
class Cooper(Car): 
    def drift(self): 
        print("Mini Coopers can drift well") 
 
class Airplanes(Vehicle): 
    def fly(self): 
        print("weeeeee I'm flying") 
 
class Tank(Vehicle): 
    #custom init because tanks have guns!~  
    #taking the gun size and tossing the rest of the arguments to the parent.  
    #if the parent doesn't find a __init__ it will keep going up until one is found or unelss we call it.  
    #Here we made a new __init__ so it doesn't go looking for one, but we call super() which is calling for the  
    #parent's __init__ 
    def __init__(self,gun_size,*args): 
        self.gun_size = gun_size 
        super(Tank,self).__init__(*args) 
    def fire(self): 
        print("pew pew pew") 
 
    #I have my custom get_stats but still calls parent's one so I don't repeat code. 
    def get_stats(self): 
        print("my gun is this big: %d " %self.gun_size) 
        super(Tank,self).get_stats() 
 
a = Cooper(150,150,"blue",4) 
a.drift() 
a.vroom() 
a.honk() 
a.get_stats() 
print(a.number_of_vehicles) 
 
b = Airplanes(200,150,"white",2) 
b.fly() 
print(b.number_of_vehicles) 
 
c = Tank(500,500,250,"Green",18) 
c.fire() 
print(c.number_of_vehicles) 
c.get_stats() 

输出:

Mini Coopers can drift well 
Cars go vroom vroom 
beep beep 
I am 150 meters long! 
I have 4 number of wheels 
I am 150 meters wide! 
My color is blue! 
1                     #vehicle count 
weeeeee I'm flying    # start of plan section 
2                     #vehicle count 
pew pew pew           #start of tank section 
3                     #vehicle count 
my gun is this big: 500   
I am 500 meters long! 
I have 18 number of wheels 
I am 250 meters wide! 
My color is Green! 

所以这篇文章的重点是向您展示继承关系。

我们有一个名为 Vehicle 的基类,它是 object 的子类。不要担心 object 如果你愿意你可以阅读它。

车辆类有一些所有车辆都会有的属性,长度、宽度、颜色、车轮。它还有一个名为 number_of_vehicles 的类变量,它跟踪 Vehicle 有多少对象实例,基本上是我们“制造”了多少 Vehicles。我们还有一些类方法,它们访问和使用我们在 __init__ 中定义的属性。您可以对它们进行数学运算,但现在我们只是将它们用作打印语句以表明它们有效。我们有一个特殊的类方法可以调用同一个类中的其他方法。所以 get_stats 调用实例中的其他 get_x 方法。这使我可以通过对象中的“一个”方法调用来调用这 4 个方法,请参阅 a.get_stats()。我们仍然可以自己调用其他方法,例如 get_color。

我们有一个名为 Car 的子类,它是一种交通工具,所以我们继承它。只有汽车可以进入 vroom,但所有汽车都可以进入 vroom,所以我们只有汽车级别的 vroom 方法。诀窍是想想这个类有什么是只有这个类的实例才有的,如果没有,我可以把它放在父类中吗?所有车辆都有轮子等等,但并非所有车辆都可以行驶(仅适用于此示例)。

我们有一个 Car 的子类,cooper(mini cooper),只有它可以漂移(再一次,对于这个例子,只有在现实生活中,漂移方法才会在车辆中使用,因为所有车辆都可以牵引,但请耐心等待) .所以这个 cooper 是唯一可以漂移的汽车,所以它在下面而不是在 Car 类中。

Tank 的子类很有趣。这里我们有基本的车辆,但我们有一些新东西,一把枪!所以我们的车辆类不能处理枪,所以我们必须创建一个新的 __init__ 方法。我们分配对象变量 gun_size,然后将坦克的其余属性传递给 Vehicle 的 __init__,因为其余属性与 Vehicle 相同。我们调用 super(Tank,self).__init__(*args) 这基本上是在说,我是坦克,这就是我,请处理我的其他属性,我的 parent 。由于坦克有枪的特殊属性,我们必须修改我们的get_stats方法,来处理gun_size属性,但坦克上的其余统计数据是和车辆一样,所以我们处理完枪之后就调用 parent 处理剩下的事情。

现在我知道这是一个非常愚蠢的例子,但我希望你能在这里找到一些有用的信息。还有其他的要点我还没有触及,但这是一个起点。所以回到你原来的问题。想抽象,最高层是形状,然后矩形是一种形状,所以他们会继承它。正方形是特殊的矩形,所以它们会继承矩形等等。

如果您有任何疑问,请随时提问。