interface.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package main
  2. import "fmt"
  3. func main() {
  4. foo1()
  5. }
  6. type Payer interface {
  7. Pay(int) error
  8. }
  9. // -----------------------------------------------------------------------------
  10. type Wallet struct {
  11. Cash int
  12. }
  13. func (w *Wallet) Pay(amount int) error {
  14. if w.Cash < amount {
  15. return fmt.Errorf("Не хватает денег в кошельке")
  16. }
  17. w.Cash -= amount
  18. return nil
  19. }
  20. // -----------------------------------------------------------------------------
  21. type Card struct {
  22. Balance int
  23. ValidUntil string
  24. Cardholder string
  25. CVV string
  26. Number string
  27. }
  28. func (c *Card) Pay(amount int) error {
  29. if c.Balance < amount {
  30. return fmt.Errorf("Не хватает денег на карте")
  31. }
  32. c.Balance -= amount
  33. return nil
  34. }
  35. // -----------------------------------------------------------------------------
  36. type ApplePay struct {
  37. Money int
  38. AppleID string
  39. }
  40. func (a *ApplePay) Pay(amount int) error {
  41. if a.Money < amount {
  42. return fmt.Errorf("Не хватает денег на аккаунте")
  43. }
  44. a.Money -= amount
  45. return nil
  46. }
  47. // -----------------------------------------------------------------------------
  48. // Здесь напрямую нельзя обриться к полю структуры, реализующей интерфейс.
  49. // Поэтому нужно делать преобразвание.
  50. func Buy(p Payer) {
  51. switch p.(type) {
  52. case *Wallet:
  53. fmt.Println("Oplata наличными?")
  54. case *Card:
  55. plasticCard, ok := p.(*Card)
  56. if !ok {
  57. fmt.Println("Не удалось преобразовать к типу *Card")
  58. }
  59. fmt.Println("Вставляйте карту,", plasticCard.Cardholder)
  60. default:
  61. fmt.Println("Что-то новое!")
  62. }
  63. err := p.Pay(10)
  64. if err != nil {
  65. fmt.Println(err)
  66. } else {
  67. fmt.Printf("Спасибо за покупку через %T\n\n", p)
  68. }
  69. }
  70. func foo1() {
  71. // myWallet := &Wallet{Cash: 100}
  72. // Buy(myWallet)
  73. var myMoney Payer
  74. myMoney = &Card{Balance: 100, Cardholder: "rvasily"}
  75. Buy(myMoney)
  76. myMoney = &ApplePay{Money: 9}
  77. Buy(myMoney)
  78. }