跟进我发布的代码片段审查问题: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 处理剩下的事情。
现在我知道这是一个非常愚蠢的例子,但我希望你能在这里找到一些有用的信息。还有其他的要点我还没有触及,但这是一个起点。所以回到你原来的问题。想抽象,最高层是形状,然后矩形是一种形状,所以他们会继承它。正方形是特殊的矩形,所以它们会继承矩形等等。
如果您有任何疑问,请随时提问。
