我正在学习python,我必须用is-a或has-a填充空白,而我并不完全清楚。所以我需要接下来的例子解释为什么它们就是这样。
以下是示例。填空是## ?? ??#。
## Animal is-a object (yes, sort of confusing) look at the extra credit
class Animal(object):
pass
## ??
class Dog(Animal):
def __init__(self, name):
## ??
self.name = name
## ??
class Cat(Animal):
def __init__(self, name):
## ??
self.name = name
## ??
class Person(object):
def __init__(self, name):
## ??
self.name = name
## Person has-a pet of some kind
self.pet = None
答案 0 :(得分:3)
我想你正在寻找:
动物是对象
狗是动物
狗有一个名称
猫是动物
Cat 有一个名称
人是对象
人具有名称
一个人有一个宠物
答案 1 :(得分:2)
技术术语是“继承”(“is-a”)与“Composition”(“has-a”)。
关于哪种情况在任何特定情况下都更好,存在很多争论。对于经典的Car
OOP模型,您可以:
class Car(object): # everything inherits from object in Py3
# stuff related to being a car
class TwoWheelDrive(Car):
# This car has two wheels that drive, so maybe
def accelerate(self, vector):
for wheel in [self.front_left_wheel, self.front_right_wheel]:
wheel.RPM += vector
class FourWheelDrive(Car):
def accelerate(self, vector):
for wheel in [self.front_left_wheel, self.front_right_wheel,
self.rear_left_wheel, self.rear_right_wheel]:
wheel.RPM += vector
my_car = FourWheelDrive(color='red',speed='super fast',coolness='very')
my_car.accelerate(float('inf')) # runs FourWheelDrive().accelerate(float('inf'))
或者你可以构建汽车所拥有的接口,而不是所有其他汽车的不同类型的汽车。
class Wheel(object):
# would probably have properties like RPM, traction, etc
class TwoWheelDriveInterface(object):
def __init__(self, *args):
self.front_left_wheel = Wheel(*args)
self.front_right_wheel = Wheel(*args)
self.rear_left_wheel = Wheel(*args)
self.rear_right_wheel = Wheel(*args)
self.wheels = [self.front_left_wheel, self.front_right_wheel,
self.rear_left_wheel, self.rear_right_wheel]
def accelerate(self, vector):
for wheel in [self.front_left_wheel, self.front_right_wheel]:
wheel.RPM += vector
class FourWheelDriveInterface(object):
def __init__(self, *args):
# same as TwoWheelDriveInterface. In fact these could both
# inherit from a common DriveInterface class and override
# accelerate! (that is, both TwoWheelDriveInterface and
# FourWheelDriveInterace ARE-A DriveInterface)
def accelerate(self, vector):
for wheel in self.wheels:
wheel.RPM += vector
class Car(object):
def __init__(self, color,speed,coolness,two_wheel_drive=False,*wheelargs):
self.color = color
self.speed = speed
self.coolness = coolness
if two_wheel_drive:
self.driveinterface = TwoWheelDrive(*wheelargs)
else:
self.driveinterface = FourWheelDrive(*wheelargs)
self.accelerate = self.driveinterface.accelerate # bind the methods together
my_car = Car(color='red',speed='very fast',coolness='very',two_wheel_drive=True)
my_car.accelerate(float('inf')) # runs TwoWheelDriveInterface().accelerate(float('inf'))
另一个常见的例子是动物园。你可能有很多动物,例如。
class Animal(object):
# attributes all animals have. Name, species, color, sound, etc?
class Kangaroo(Animal):
# override attributes from Animal to make them specific to Kangas
class Lion(Animal):
# see above
class Hyena(Animal):
class Monkey(Animal):
class Chimp(Monkey):
# Chimps are-a monkey, which is-an Animal
class Bear(Animal):
# etc etc ad nauseam, however....
class Zoo(Animal): # NO!
动物园不是动物。它可能具有几种与Animal相同的特性,甚至可能使代码看起来更清洁乍一看。毕竟,“干”对吗?我们可以覆盖我们不需要的东西。然而,这显然是一种构成,而不是继承。一个动物园有动物,它本身不是动物
class Zoo(object):
def __init__(self, zoo_name, zoo_location, zoo_animals):
self.name = zoo_name
self.location = zoo_location
self.animals = zoo_animals
# zoo_animals in this case should be a list of Animal objects
ny_zoo = Zoo("New York Zoo", "New York", [Bear(), Lion(), Chimp(), Kangaroo()])
# ny_zoo HAS the following animals:
# # Bear
# # Lion
# # Chimp
# # Kangaroo