Объектно-ориентированное программирование с помощью Python [Ирв Кальб] (pdf) читать постранично, страница - 89

-  Объектно-ориентированное программирование с помощью Python  11.15 Мб, 515с. скачать: (pdf) - (pdf+fbd)  читать: (полностью) - (постранично) - Ирв Кальб

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

произвольный цвет и произвольное местоположение:
self.window = window
self.color = random.choice((RED, GREEN, BLUE))
self.x = random.randrange(1, maxWidth – 100)
self.y = random.randrange(1, maxHeight – 100)

И наконец, каждый класс устанавливает переменную экземпляра self.shapeType в соответствующую строку.
Всякий раз, находя набор классов, который реализует абсолютно одинаковый метод и/или содержит общий код в методе
с общим именем, мы должны признать его хорошим кандидатом для наследования.

318 Часть III. Инкапсуляция, полиморфизм и наследование

Давайте извлечем общий код из трех классов и создадим общий базовый класс с именем Shape, продемонстрированный
в листинге 10.6.
Файл: InheritedShapes/ShapeBasic.py
# Класс Shape – базовый
import random
# Настраиваем цвета
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
class Shape():


def __init__(self, window, shapeType, maxWidth, maxHeight):
self.window = window
self.shapeType = shapeType
self.color = random.choice((RED, GREEN, BLUE))
self.x = random.randrange(1, maxWidth – 100)
self.y = random.randrange(25, maxHeight – 100)



def getType(self):
return self.shapeType
Листинг 10.6. Класс Shape для использования в качестве базового класса

Класс состоит только из двух методов: __init__() и
getType(). Метод __init__()  запоминает данные, переда-

ваемые в переменные экземпляров, затем произвольным образом выбирает цвет и начальное местоположение (self.x
и self.y). Метод getType() лишь возвращает тип фигуры,
заданной инициализацией.
Теперь мы можем написать любое число подклассов, которые наследуют от Shape. Создадим три подкласса, которые будут вызывать метод __init__() класса Shape, передавая строку, определяющую его тип и размер окна. Метод getType()
появится лишь в классе Shape, поэтому любой клиентский вызов getType() будет обрабатываться этим методом в унаследованном классе Shape. Мы начнем с кода класса Square, который продемонстрирован в листинге 10.7.

Глава 10. Наследование 319

Файл: InheritedShapes/Square.py
# Класс Square
import pygame
from Shape import *
class Square(Shape): 
def __init__(self, window, maxWidth, maxHeight):
super().__init__(window, 'Square', maxWidth, maxHeight) 
self.widthAndHeight = random.randrange(10, 100)
self.rect = pygame.Rect(self.x, self.y, self.widthAndHeight,
self.widthAndHeight)
def clickedInside(self, mousePoint): 
clicked = self.rect.collidepoint(mousePoint)
return clicked
def getArea(self): 
theArea = self.widthAndHeight * self.widthAndHeight
return theArea
def draw(self): 
pygame.draw.rect(self.window, self.color,
(self.x, self.y, self.widthAndHeight,
self.widthAndHeight))
Листинг 10.7. Класс Square, который наследует от класса Shape

Класс Square начинается с наследования от класса Shape .
Метод __init__() вызывает метод __init__() его базового
класса (или суперкласса) , определяя фигуру как квадрат
и произвольно выбирая ее размер.
Далее у нас идут три метода, реализация которых специфична для квадрата. Методу clickedInside() всего лишь требуется вызвать rect.collidepoint(), чтобы определить, был ли
щелчок внутри прямоугольника . Метод getArea() просто
умножает widthAndHeight на widthAndHeight . И наконец,
метод draw() рисует прямоугольник с помощью значения
widthAndHeight .
В листинге 10.8 продемонстрирован класс Circle, который
также был изменен, чтобы наследовать от класса Shape.

320 Часть III. Инкапсуляция, полиморфизм и наследование

Файл: InheritedShapes/Circle.py
# Класс Circle
import pygame
from Shape import *
import math
class Circle(Shape):
def __init__(self, window, maxWidth, maxHeight):
super().__init__(window, 'Circle', maxWidth, maxHeight)
self.radius = random.randrange(10, 50)
self.centerX = self.x + self.radius
self.centerY = self.y + self.radius
self.rect = pygame.Rect(self.x, self.y, self.radius * 2,
self.radius * 2)
def clickedInside(self, mousePoint):
theDistance = math.sqrt(((mousePoint[0] – self.centerX) ** 2) +
((mousePoint[1] – self.centerY) ** 2))
if theDistance