Изменение функции-члена в производном классе в Python 3

#python #python-3.x #oop

#python #python-3.x #ооп

Вопрос:

shape определяется как базовый класс. Классы rectangle и circle являются классами, производными от класса shape . Я пытаюсь создать новый производный класс car , который наследует от обоих circle и rectangle . Любой экземпляр class будет представлять собой прямоугольник и два круга под прямоугольником. Однако я не мог понять, как переопределить set_color() , чтобы я мог устанавливать разные цвета для прямоугольника и колес circle . Заранее спасибо.

     !pip install calysto

from calysto.graphics import *
from calysto.display import display, clear_output
import time
import math

CANVAS_240 = Canvas(size=(400, 400))

class shape:

  color = None
  x = None
  y = None
 
  def set_color(self, red, green, blue):
    self.color = (red, green, blue)
 
  def move_to(self, x, y):
    self.x = x
    self.y = y

  def move_on_line(self, x_fin, y_fin, count_of_steps):
    delta_x = (x_fin - self.x)/count_of_steps
    delta_y = (y_fin - self.y)/count_of_steps
    while self.x != x_fin and self.y != y_fin:
      shape_has_color = self.color 
      self.set_color(255,255,255)
      self.draw()
      self.color = shape_has_color
      self.move_to(self.x delta_x,self.y delta_y)
      self.draw()

  def displace(self, delta_x, delta_y):
    shape_has_color = self.color
    self.set_color(255, 255, 255) # that is white. i.e. the background color
    self.draw()
    self.color = shape_has_color
    self.move_to(self.x delta_x, self.y delta_y)
    self.draw()

  def __str__(self):
    return "shape object: color=%s coordinates=%s" % (self.color, (self.x, self.y))

  def __init__(self, x, y):
    self.x = x
    self.y = y

  def displace(self, delta_x, delta_y):
    shape_has_color = self.color
    self.set_color(255, 255, 255) # that is white. i.e. the background color
    self.draw()
    self.color = shape_has_color
    self.move_to(self.x delta_x, self.y delta_y)
    self.draw()

class circle(shape):

  radius = None

  def __init__(self, x, y, radius):
    self.x = x
    self.y = y
    self.radius = radius
    self.set_color(255, 0, 0)
     
  def draw(self):
    c = Circle((self.x, self.y), self.radius)
    c.fill(Color(self.color[0], self.color[1], self.color[2]))
    c.noStroke()
    clear_output(wait=True)
    c.draw(CANVAS_240)
    display(CANVAS_240)
    
    
    
class rectangle(shape):

  width = None
  height = None

  def __init__(self, x, y, width, height):
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.set_color(255, 0, 0)
     
  def draw(self):
    rb = (self.x self.width, self.y)
    ru = (self.x self.width, self.y self.height)
    lu = (self.x, self.y self.height)
    lb = (self.x, self.y)
    r = Polygon([lb,rb,ru,lu])
    r.fill(Color(self.color[0], self.color[1], self.color[2]))
    r.noStroke()
    clear_output(wait=True)
    r.draw(CANVAS_240)
    display(CANVAS_240)

class triangle(shape):
  dx2 = None
  dy2 = None
  dx3 = None
  dy3 = None

  def __init__(self, x,y,dx2,dy2,dx3,dy3):
    self.x = x
    self.y = y
    self.dx2 = dx2
    self.dy2 = dy2
    self.dx3 = dx3
    self.dy3 = dy3
    self.set_color(255,0,0)
  
  def draw(self):
    fi = (self.x,self.y)
    se = (self.x   self.dx2,self.y self.dy2)
    th = (self.x self.dx3,self.y self.dy3)
    t = Polygon([fi,se,th])
    t.fill(Color(self.color[0], self.color[1], self.color[2]))
    t.noStroke()
    clear_output(wait=True)
    t.draw(CANVAS_240)
    display(CANVAS_240)

class car(rectangle,circle):
  width = None
  height = None
  radius = None

  def __init__(self, x, y, width, height, radius):
    rectangle.__init__(self,x,y,width,height)
    circle.__init__(self,x,y,radius)
    self.set_color(255,0,0)


  def draw(self):
    rb = (self.x self.width, self.y)
    ru = (self.x self.width, self.y   self.height)
    lb = (self.x,self.y)
    lu = (self.x,self.y self.height)
    r = Polygon([lb,rb,ru,lu])
    w1 = Circle((self.x, self.y self.height), self.radius)
    w2 = Circle((self.x self.width, self.y self.height), self.radius)
    r.fill(Color(self.color[0], self.color[1], self.color[2]))
    r.noStroke()
    w1.fill(Color(self.color[0], self.color[1], self.color[2]))
    w1.noStroke()
    w2.fill(Color(self.color[0], self.color[1], self.color[2]))
    w2.noStroke()
    clear_output(wait=True)
    r.draw(CANVAS_240)
    w1.draw(CANVAS_240)
    w2.draw(CANVAS_240)
    display(CANVAS_240)
 

Комментарии:

1. set_color необходимо вызвать circle.set_color и rectangle.set_color явно. Кроме того, это не похоже на хорошее использование (множественного) наследования, рассмотрите возможность использования композиции вместо этого.

Ответ №1:

Для решения этой проблемы было бы более эффективно, если бы вместо наследования использовалась композиция.Композиция позволяет повторно использовать реализацию компонентов, которые она содержит.Составной класс (вновь сформированный класс) не наследует интерфейс компонентного класса, но может использовать его реализацию.В этом случае объект класса car представляет собой комбинацию двух объектов класса circle и одного объекта класса rectangle, но не является производным объектом ни одного из них.Таким образом, он может быть создан как:

 class car:
   def __init__(self,body,wheel):
      self.body=body
      self.wheel=wheel
#Here body is an object of **rectangle** class and wheel is an object of **circle** class
      #color of wheel and body can be independently set as
   def set_color(self,body_color,wheel_color):
      self.wheel.set_color(wheel_color)
      self.body.set_color(body_color)
#Accordingly draw method will change