Car
, Product
, Store
. Класс Car
представлял конкретную машину в магазине, а класс Product
– некий товар, включая машины. В свою очередь, класс Store
представлял сам магазин, включая список товаров на складе и список проданных товаров.Car
может содержать любые атрибуты автомобиля.Product
должен содержать атрибуты товара, то есть его наименование, количество на складе и стоимость. Машина является товаром, но в магазине есть и другие товары, поэтому атрибуты машины можно возвести к Product
. Класс Product
должен содержать методы для отображения товара и его статуса – на складе либо продан.Store
должны присутствовать следующие атрибуты и методы:Car
: представляет конкретную машину в магазине. Содержит поле Product
, которое означает, что в нём есть все атрибуты и методы структуры Product
.Product
: представляет товар в магазине, включая машины. Содержит атрибуты товара, такие как его наименование (Name
), остаток на складе (Quantity
) и цена (Price
). Реализует интерфейс ProductInterface
, определяющий методы, которые должен реализовывать Product
.Store
: представляет магазин по продаже товаров, включая машины. Содержит список товаров на складе и список проданных товаров. Реализует интерфейс StoreInterface
, определяющий методы, которые должен реализовывать Store
.package main
import "fmt"
// Класс Product должен иметь атрибуты товара (то есть наименование, количество на складе и цену)
type Product struct {
Name string
Quantity int
Price float64
}
// Car. Машина является лишь одним из товаров, то есть в магазине могут быть и другие, поэтому её атрибут также относится к Product.
type Car struct {
Product
}
// ProductInterface Класс Product должен содержать методы для отображения товара и его статуса – продан или на складе.
type ProductInterface interface {
DisplayProduct()
DisplayStatus()
}
// Класс Store должен содержать:
// функцию DisplayProduct для отображения товара.
func (p Product) DisplayProduct() {
fmt.Printf("Product: %s", p.Name)
}
// функцию DisplayStatus для отображения статуса товара.
func (p Product) DisplayStatus() {
if p.Quantity > 0 {
fmt.Println("In stock")
} else {
fmt.Println("Out of stock")
}
}
// Класс Store должен содержать следующие атрибуты и методы: количество товаров в магазине, добавление товара, вывод списка всех элементов товаров, продажа элемента, вывод списка проданных товаров и их общей суммы.
type Store struct {
Product []ProductInterface
soldProduct []ProductInterface
}
// StoreInterface. Класс Store должен содержать методы для добавления товара, вывода всех товаров, продажи товара и вывода списка проданных товаров.
type StoreInterface interface {
AddProduct(ProductInterface)
ListProducts()
SellProduct(string)
ListSoldProducts()
}
// AddProduct. Класс Store должен содержать методы для добавления товара, вывода всех товаров, продажи товара и вывода списка проданных товаров.
func (s *Store) AddProduct(p ProductInterface) {
s.Product = append(s.Product, p)
}
// ListProducts. Класс Store должен содержать методы для добавления товара, вывода всех товаров, продажи товара и вывода списка проданных товаров.
func (s *Store) ListProducts() {
for _, p := range s.Product {
p.DisplayProduct()
}
}
// SellProduct. Класс Store должен содержать методы для добавления товара, вывода всех товаров, продажи товара и вывода списка проданных товаров.
func (s *Store) SellProduct(name string) {
// Перебор товаров магазина.
for i, p := range s.Product {
// Если товар найден, он удаляется из магазина и добавляется в срез проданных товаров.
if p.(Car).Name == name {
s.soldProduct = append(s.soldProduct, p)
s.Product = append(s.Product[:i], s.Product[i+1:]...)
}
}
}
// ListSoldProducts. Класс Store должен содержать методы для добавления товара, вывода всех товаров, продажи товара и вывода списка проданных товаров.
func (s *Store) ListSoldProducts() {
for _, p := range s.soldProduct {
p.DisplayProduct()
}
}
func main() {
//Создание магазина.
store := Store{}
//Создание товара.
car := Car{Product{Name: "Toyota", Quantity: 10, Price: 100000}}
//Добавление товара в магазин.
store.AddProduct(car)
//Продажа товара.
store.SellProduct("Toyota")
//Вывод списка всех товаров магазина.
store.ListProducts()
//Вывод всех проданных товаров.
store.ListSoldProducts()
}
Product
содержали получателей указателей и получателей значений, что документацией Go не рекомендуется. Кроме того, структура Car
содержала поле Product
, но оно не было определено как тип.Car
как содержащую поле Product
. Это значит, что у неё есть все атрибуты и методы структуры Product
.Product
как реализующую интерфейс ProductInterface
, определяющий методы, которые должен реализовывать Product
.Store
как реализующую интерфейс StoreInterface
, определяющий методы, которые должен реализовывать Store
.Product
, чтобы они содержали только получателей указателей.Store
можно использовать для управления товарным учётом и продажами, а классы Product
и Car
– для представления и управления товарами и машинами.Car
, Product
и Store
можно реализовать следующими этапами:Car
нужно внести атрибуты, описывающие конкретную машину, а именно её Make
, Model
и Year
.Product
нужно включить атрибуты, описывающие товар, а именно его Name
, Quantity
и Price
. Этот класс также должен содержать методы для отображения товара и его статуса (продан или на складе).Store
нужно добавить атрибуты, отслеживающие количество товаров на складе, список товаров на складе и список проданных товаров. Этот класс также должен содержать методы для добавления товара, вывода списка товаров, продажи товара и вывода списка проданных товаров.Product
, который будет использоваться классами Car
и Store
. Он будет иметь атрибуты Name
, Quantity
и Price
, а также методы DisplayProduct()
и DisplayStatus()
.Car
, имеющий тип Product
. Этот класс будет содержать атрибуты, наследуемые от класса Product
, а также дополнительные, относящиеся конкретно к автомобилю, то есть Make
, Model
и Year
.Store
, который будет содержать атрибуты SoldProducts
и Products
для отслеживания проданных товаров и товаров на складе соответственно. В нём также будут присутствовать методы AddProduct()
, ListProducts()
, SellProduct()
и ListSoldProducts()
.package main
import "fmt"
// Класс Car представляет конкретную машину.
type Car struct {
Make string
Model string
Year int
Product
}
// Класс Product представляет товар в магазине, включая машины.
// Он содержит атрибуты товара, такие как его name, quantity и price.
type Product struct {
Name string
Quantity int
Price float64
}
// Интерфейс ProductInterface определяет методы, которые должен реализовывать Product.
type ProductInterface interface {
DisplayProduct()
DisplayStatus()
UpdateQuantity(int) error
}
// DisplayProduct – это метод класса Product, отображающий информацию о товаре.
func (p Product) DisplayProduct() {
fmt.Printf("Product: %s\n", p.Name)
fmt.Printf("Quantity: %d\n", p.Quantity)
fmt.Printf("Price: $%.2f\n", p.Price)
}
// DisplayStatus – это метод класса Product, отображающий статус товара (продан или на складе).
func (p Product) DisplayStatus() {
if p.Quantity > 0 {
fmt.Println("Status: In stock")
} else {
fmt.Println("Status: Out of stock")
}
}
// UpdateQuantity – это метод класса Product, обновляющий количество товара на складе.
func (p Product) UpdateQuantity(quantity int) error {
if p.Quantity+quantity < 0 {
return fmt.Errorf("cannot set quantity to a negative value")
}
p.Quantity += quantity
return nil
}
// Класс Store представляет магазин, продающий товары, в том числе машины.
// Он содержит список товаров на складе и список проданных товаров.
type Store struct {
Products []ProductInterface
SoldProducts []ProductInterface
}
// Интерфейс StoreInterface определяет методы, которые должен реализовывать Store.
type StoreInterface interface {
AddProduct(ProductInterface)
ListProducts()
SellProduct(string) error
ListSoldProducts()
SearchProduct(string) ProductInterface
}
// AddProduct – это метод класса Store, добавляющий товар в список товаров на складе.
func (s *Store) AddProduct(p ProductInterface) {
s.Products = append(s.Products, p)
}
// ListProducts – это метод класса Store, выводящий список всех товаров на складе.
func (s *Store) ListProducts() {
for _, p := range s.Products {
p.DisplayProduct()
p.DisplayStatus()
fmt.Println()
}
}
// SellProduct – это метод класса Store, продающий товар из списка товаров на складе и добавляющий его в список проданных товаров.
func (s *Store) SellProduct(name string) error {
// Поиск товара в списке товаров на складе.
product := s.SearchProduct(name)
if product == nil {
return fmt.Errorf("product not found")
}
//Утверждение, что товар имеет тип Product.
p, ok := product.(*Product)
if !ok {
return fmt.Errorf("product is not a Product type")
}
// Проверяет, достаточно ли на складе товара для его продажи.
if p.Quantity < 1 {
return fmt.Errorf("product is out of stock")
}
// Удаляет товар из списка товаров на складе и добавляет его в список проданных товаров.
for i, p := range s.Products {
// Утверждает, что переменная p имеет тип Product.
p, ok := p.(*Product)
if !ok {
return fmt.Errorf("product has wrong type")
}
if p.Name == name {
s.SoldProducts = append(s.SoldProducts, p)
s.Products = append(s.Products[:i], s.Products[i+1:]...)
break
}
}
// Обновляет количество товаров на складе.
err := product.UpdateQuantity(-1)
if err != nil {
return err
}
return nil
}
// ListSoldProducts – это метод класса Store, выводящий список всех проданных товаров.
func (s *Store) ListSoldProducts() {
for _, p := range s.SoldProducts {
p.DisplayProduct()
fmt.Println()
}
}
// SearchProduct – это метод класса Store, ищущий товар с заданным наименованием в списке товаров на складе.
// При обнаружении этого товара он его возвращает. В противном случае возвращается нуль.
func (s *Store) SearchProduct(name string) ProductInterface {
for _, p := range s.Products {
// Утверждает, что переменная p имеет тип Product.
p, ok := p.(*Product)
if !ok {
return nil
}
if p.Name == name {
return p
}
}
return nil
}
func main() {
// Создаёт новый магазин.
store := &Store{}
// Добавляет в магазин машины.
store.AddProduct(&Car{Make: "Toyota", Model: "Camry", Year: 2020, Product: Product{Name: "Toyota Camry", Quantity: 3, Price: 30000}})
store.AddProduct(&Car{Make: "Honda", Model: "Accord", Year: 2021, Product: Product{Name: "Honda Accord", Quantity: 5, Price: 35000}})
store.AddProduct(&Car{Make: "Ford", Model: "Mustang", Year: 2019, Product: Product{Name: "Ford Mustang", Quantity: 2, Price: 40000}})
// Выводит список товаров в магазине.
fmt.Println("Products in stock:")
store.ListProducts()
fmt.Println()
// Продаёт машину из магазина.
err := store.SellProduct("Toyota Camry")
if err != nil {
fmt.Println(err)
}
// Снова выводит список товаров.
fmt.Println("\nProducts in stock:")
store.ListProducts()
fmt.Println()
// Выводит проданные товары.
fmt.Println("\nSold products:")
store.ListSoldProducts()
}
Car
, Product
и Store
. Класс Car
представляет конкретный автомобиль и может содержать любые выбранные нами атрибуты. Класс Product
представляет товар в магазине, включая машины. Он содержит атрибуты товара, такие как Name
, Quantity
и Price
. Кроме того, этот класс содержит методы для отображения товара и его статуса (продан либо на складе).Store
представляет сам магазин и содержит такие атрибуты, как количество проданных и оставшихся товаров, а также методы для добавления товара, вывода списка всех товаров, продажи товара и вывода списка проданных товаров.Product
и Car
были определены верно, а вот с классом Store
были проблемы. Во-первых, срез Product
в структуре Store
был определён как срез значений Product
при том, что должен был быть определён как срез значений ProductInterface
, поскольку класс Product
не реализует интерфейс ProductInterface
. Это вызывало ошибку компиляции при попытке использовать метод SellProduct
, так как значения Product
в срезе Product
не содержали необходимых методов.SellProduct
класса Store
. В нём значение продаваемого Product
удалялось из среза Product
, но в срез soldProduct
не добавлялось. В результате метод ListSoldProducts
всегда возвращал пустой срез.Store
, чтобы определить срез Product
как срез значений ProductInterface
, а также добавили в метод SellProduct
строчку кода для внесения проданного Product
в срез soldProduct
. Кроме того, мы добавили в этот метод обработку ошибок для случаев, когда товар не был найден или отсутствовал на складе.Играй в нашу новую игру прямо в Telegram!
К сожалению, не доступен сервер mySQL