- Напишем свой класс
- Доступ к атрибутам экземпляра класса
- Методы класса
- Разграничение доступа к методам
- Алиасы
- Наследование
- Модули
- Вызовы классов и модулей
- method_missing
Напишем свой класс
class Bus
def initialize(params)
# переменная с @ - переменная класса
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print "
Vehicle: #{@type.upcase}\n
Color: #{@color.upcase}\n
Doors: #{@doors_number}\n
Wheels number: #{@wheels_number}\n
Wheels radius: #{@wheels_radius}\n
"
end
end
Bus.new(color: 'red', wheels_radius: 18)
Доступ к атрибутам экземпляра класса
bus = Bus.new(color: 'red', wheels_radius: 18)
# bus.color undefined method `color'
bus.color = 'green'
class Bus
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def color
@color
end
def color=(color)
@color = color
end
def print_string
print "
Vehicle: #{@type.upcase}\n
Color: #{@color.upcase}\n
Doors: #{@doors_number}\n
Wheels number: #{@wheels_number}\n
Wheels radius: #{@wheels_radius}\n
"
end
end
class Bus
# Создание методов-геттеров
attr_reader :color, :doors_number, :type, :wheels_number, :wheels_radius
# Создание методов-сеттеров
attr_writer :color, :doors_number, :type, :wheels_number, :wheels_radius
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print "
Vehicle: #{type.upcase}\n
Color: #{color.upcase}\n
Doors: #{doors_number}\n
Wheels number: #{wheels_number}\n
Wheels radius: #{wheels_radius}\n
"
end
end
bus = Bus.new(color: 'red', wheels_radius: 18)
bus.color
bus.color = 'green'
Методы класса
class Bus
def self.bus?
true
end
end
Bus.bus? # true
Разграничение доступа к методам
class Bus
# Геттеры и сеттеры
attr_accessor :color, :doors_number, :type, :wheels_number, :wheels_radius
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print bus_string_of(self)
end
def bus_string_of(bus)
bus.bus_string
end
protected
def bus_string
"
Vehicle: #{upcase_attribute(type)}\n
Color: #{upcase_attribute(color)}\n
Doors: #{upcase_attribute(doors_number)}\n
Wheels number: #{upcase_attribute(wheels_number)}\n
Wheels radius: #{upcase_attribute(wheels_radius)}\n
"
end
private
def upcase_attribute(attribute)
attribute.to_s.upcase
end
end
bus = Bus.new(color: 'red', wheels_radius: 18)
bus.print_string
bus.bus_string(bus)
bus.bus_string_of(bus)
Алиасы
class Bus
attr_accessor :color
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print bus_string_of(self)
end
alias to_s print_string
def bus_string_of(bus)
bus.bus_string
end
protected
def bus_string
"
Vehicle: #{upcase_attribute(@type)}\n
Color: #{upcase_attribute(@color)}\n
Doors: #{upcase_attribute(@doors_number)}\n
Wheels number: #{upcase_attribute(@wheels_number)}\n
Wheels radius: #{upcase_attribute(@wheels_radius)}\n
"
end
private
def upcase_attribute(attribute)
attribute.to_s.upcase
end
end
bus = Bus.new(color: 'red', wheels_radius: 18)
bus.to_s
bus.to_string
Наследование
class Bus
attr_accessor :color
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print bus_string_of(self)
end
def bus_string_of(bus)
bus.bus_string
end
protected
def bus_string
"
Vehicle: #{upcase_attribute(@type)}\n
Color: #{upcase_attribute(@color)}\n
Doors: #{upcase_attribute(@doors_number)}\n
Wheels number: #{upcase_attribute(@wheels_number)}\n
Wheels radius: #{upcase_attribute(@wheels_radius)}\n
"
end
private
def upcase_attribute(attribute)
attribute.to_s.upcase
end
alias to_s print_string
end
class OfficeBus < Bus
attr_reader :people_place
def initialize(params)
super
@people_place = params[:people_place]
end
def has_people_place?
people_place
end
protected
def bus_string
"
Vehicle: #{upcase_attribute(@type)}\n
People place: #{@people_place ? 'YES' : 'NO'}
Color: #{upcase_attribute(@color)}\n
Doors: #{upcase_attribute(@doors_number)}\n
Wheels number: #{upcase_attribute(@wheels_number)}\n
Wheels radius: #{upcase_attribute(@wheels_radius)}\n
"
end
end
class Bus
end
class OfficeBus < Bus
end
OfficeBus.new(color: 'red', wheels_radius: '18', people_place: true).to_s
Модули
# include
module Colorful
COLORS = {
black: '#000000',
red: '#FF0000',
white: '#FFFFFF',
}
def color_code(color)
COLORS[color.to_sym]
end
end
class Car
def car?
true
end
end
class User
# include расширяет экземпляры класса
# Модуль используется как mixin
# Перезаписывает методы класса, если есть с таким же именем
include Colorful
#...
end
class Bus
attr_accessor :color
include Colorful
def initialize(params)
@color = params[:color]
@doors_number = 4
@type = 'Bus'
@wheels_number = 4
@wheels_radius = params[:wheels_radius]
end
def print_string
print bus_string_of(self)
end
def bus_string_of(bus)
bus.bus_string
end
protected
def bus_string
"
Vehicle: #{upcase_attribute(@type)}\n
Color: #{upcase_attribute(@color)}\n
Doors: #{upcase_attribute(@doors_number)}\n
Wheels number: #{upcase_attribute(@wheels_number)}\n
Wheels radius: #{upcase_attribute(@wheels_radius)}\n
"
end
private
def upcase_attribute(attribute)
attribute.to_s.upcase
end
alias to_s print_string
end
bus = Bus.new(color: 'red', wheels_radius: '18')
bus.color_code(bus.color)
## extend ##
module Colorful
def colorized?
true
end
end
class Bus
# extend расширяет класс
extend Colorful
#...
end
Bus.colorized?
Вызовы классов и модулей
# Короткая запись - Books::HarryPotter.glasses
module HarryPotter
def self.magic
pp 'magic'
end
end
module Books
module HarryPotter
def self.glasses
pp 'glasses'
end
end
# Вызов метода из модуля Books::HarryPotter
HarryPotter::glasses
# Вызов метода из модуля HarryPotter (который находится глобально)
::HarryPotter::magic
end
# => "glasses"
# => "magic"
method_missing
def method_missing(m, *args, &block)
#...
end
# Стараемся использовать отдельный файл для каждого класса
# Один модуль - один файл
# ruby run.rb
Самостоятельная работа
Создайте классы для представления точек и отрезков.
Класс
Point
:- Методы:
distance_to(other_point)
- метод, который вычисляет расстояние до другой точки.
- Методы:
Класс
Segment
:- Методы:
length
- метод, который возвращает длину отрезка.midpoint
- метод, который возвращает среднюю точку отрезка.
- Методы:
Для точек и сегмента добавьте строковое представление, которое выводит текущие координаты:
Пример использования:
point1 = Point.new(1, 2)
point2 = Point.new(4, 6)
segment = Segment.new(point1, point2)
puts "Длина отрезка: #{segment.length}" # => Длина отрезка: 5.0
puts "Средняя точка отрезка: #{segment.midpoint}" # => Средняя точка отрезка: [2.5, 4.0]
puts "Координаты отрезка: #{segment}" # => Координаты отрезка: [[1, 2], [4, 6]]
Реализуйте указанные классы и методы, а также протестируйте их, используя примеры использования.
Пример реализации
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def distance_to(other_point)
Math.sqrt((other_point.x - @x)**2 + (other_point.y - @y)**2)
end
def to_s
"[#{@x}, #{@y}]"
end
end
class Segment
attr_reader :start_point, :end_point
def initialize(start_point, end_point)
@start_point = start_point
@end_point = end_point
end
def length
@start_point.distance_to(@end_point)
end
def midpoint
mid_x = (@start_point.x + @end_point.x) / 2.0
mid_y = (@start_point.y + @end_point.y) / 2.0
Point.new(mid_x, mid_y)
end
def to_s
"[#{@start_point}, #{@end_point}]"
end
end
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.