Расскажите об объектно-ориентированном программировании в Go.

Go
Расскажите об объектно-ориентированном программировании в Go.

Мы знаем, что в языке Go нет понятия класса (Class), но это не значит, что язык Go не поддерживаетОбъектно-ориентированное программирование, в конце концов, объектно-ориентированный — это всего лишь идея программирования.

Напомним три основные характеристики объектной ориентации:

  1. Инкапсуляция: скройте свойства и детали реализации объекта и предоставьте публичный доступ только внешнему миру.
  2. Наследование: сделайте так, чтобы подкласс имел свойства и методы родительского класса, или переопределите или добавьте свойства и методы и т. д.
  3. Полиморфизм: разные реализации одного и того же поведения в разных объектах.

Давайте посмотрим, как язык Go реализует эти три характеристики без использования классов.

упаковка

"Добрый"

Доступно на языке Goструктура(Structs) инкапсулирует свойства, а структура похожа на упрощенную форму класса.

Например, мы хотим определить прямоугольник, каждый прямоугольник имеет длину и ширину, мы можем инкапсулировать его следующим образом:

type Rectangle struct {
	Length int
	Width int
}

метод

Теперь, когда есть «класс», вы можете спросить, что такое «класс».методкуда?

Язык Go также имеетметод(Methods):На приемнике используются методы Go (receiver), получатель — это переменная некоторого типа. Итак, методы — это особый тип функций.

Формат определения метода следующий:

func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }

Выше мы определили прямоугольникRectangle, теперь мы хотим определить методArea()вычислить его площадь:

package main

import (
	"fmt"
)

// 矩形结构体
type Rectangle struct {
	Length int
	Width  int
}

// 计算矩形面积
func (r *Rectangle) Area() int {
	return r.Length * r.Width
}

func main() {
	r := Rectangle{4, 2}
	// 调用 Area() 方法,计算面积
	fmt.Println(r.Area())
}

Приведенный выше фрагмент кода выводит результат 8.

разрешение на доступ

Мы часто говорим, что свойства классаобщественныйвсе ещечастныйДа, в других языках программирования мы обычноpublicа такжеprivateключевое слово для выражения такого права доступа.

Не в Gopublic,private,protectedТакой модификатор контроля доступа, этоУправляйте видимостью с помощью регистра буквиз.

Если имена определенных констант, переменных, типов, интерфейсов, структур, функций и т. д. начинаются с заглавной буквы, это означает, что они могут использоватьсядругие пакетыдоступ или вызов (эквивалентноpublic); начало без заглавной буквы можно использовать только вИспользование в сумке(эквивалентноprivate).

Доступ к неэкспортированным полям

при встречеНеэкспортированные поля, которые можно использовать только внутри пакетаКак мы можем получить к нему доступ?

Как и другие объектно-ориентированные языки, Go имеет реализацииgetterа такжеsetterПуть:

  • заsetterиспользование методаSetприставка
  • заgetterметодИспользовать только имя участника

Например, сейчас у нас естьpersonв упаковкеPersonСтруктура:

package person

type Person struct {
	firstName string
	lastName  string
}

Мы видим, что две его переменные-членыначинаться с не прописной буквы, можно использовать только внутри пакета, и теперь мыfirstNameопределятьsetterа такжеgetter:

// 获取 firstName
func (p *Person) FirstName() string {
	return p.firstName
}

// 设置 firstName
func (p *Person) SetFirstName(newName string) {
	p.firstName = newName
}

Таким образом, мы можемmainУстановка и приобретение в пакетеfirstNameзначение:

package main

import (
	"fmt"

	"./person"
)

func main() {
	p := new(person.Person)
	p.SetFirstName("firstName")
	fmt.Println(p.FirstName())
}

/* Output:
firstName
*/

наследовать

Не в Goextendsключевое слово, которое используетВстраивание анонимных типов в структурыметод реализации наследования.

Анонимные типы: то есть эти типы не имеют явного имени.

Методы встроенных структур можно вызывать непосредственно для экземпляров внешнего типа:

package main

import (
	"fmt"
	"math"
)

type Point struct {
	x, y float64
}

func (p *Point) Abs() float64 {
	return math.Sqrt(p.x*p.x + p.y*p.y)
}

type NamedPoint struct {
	Point
	name string
}

func main() {
	n := &NamedPoint{Point{3, 4}, "Pythagoras"}
	fmt.Println(n.Abs()) // 打印5
}

полиморфизм

В объектно-ориентированном подходе характеристики полиморфизма следующие:Разные реализации одного и того же поведения в разных объектах. Доступно на языке Goинтерфейсреализовать эту функцию.

Сначала определим квадратSquareи прямоугольникRectangle:

// 正方形
type Square struct {
	side float32
}

// 长方形
type Rectangle struct {
	length, width float32
}

Затем мы надеемся, что сможем вычислить площадь этих двух геометрий. Но так как их площадь вычисляется по-разному, нам нужно определить два разныхArea()метод.

Итак, мы можем определитьArea()интерфейс методаShaper,ПозволятьSquareа такжеRectangleреализовать этот интерфейсArea():

// 接口 Shaper
type Shaper interface {
	Area() float32
}

// 计算正方形的面积
func (sq *Square) Area() float32 {
	return sq.side * sq.side
}

// 计算长方形的面积
func (r *Rectangle) Area() float32 {
	return r.length * r.width
}

мы можемmain()Функция называется такArea():

func main() {
	r := &Rectangle{10, 2}
	q := &Square{10}

	// 创建一个 Shaper 类型的数组
	shapes := []Shaper{r, q}
	// 迭代数组上的每一个元素并调用 Area() 方法
	for n, _ := range shapes {
		fmt.Println("图形数据: ", shapes[n])
		fmt.Println("它的面积是: ", shapes[n].Area())
	}
}

/*Output:
图形数据:  &{10 2}
它的面积是:  20
图形数据:  &{10}
它的面积是:  100
*/

Из вывода приведенного выше кода мы видим, что:различные вызовы объектовArea()методы дают разные результаты, показывая характеристики полиморфизма.

Суммировать

  • Три основные характеристики объектно-ориентированного подхода: инкапсуляция, наследование и полиморфизм.
  • Использование языка GoструктураИнкапсулируйте свойства, структуры похожи на упрощенную форму классов
  • В Go методы воздействуют на получателя (receiver), получатель — это переменная некоторого типа
  • Регистр первой буквы имени определяет, могут ли переменная/константа/тип/интерфейс/структура/функция... быть импортированы внешними пакетами
  • Поля, которые нельзя импортировать, можно использоватьgetterа такжеsetterспособ доступа
  • Использование языка GoВстраивание анонимных типов в структурыметод реализации наследования
  • Полиморфизм с использованием интерфейсов

использованная литература


прошлый обзор


🐱

Если вы считаете, что статья написана хорошо, пожалуйста, сделайте мне две маленькие одолжения:

  1. Ставьте лайк и подписывайтесь на меня, пусть эту статью увидит больше людей
  2. Обратите внимание на общественный номер»программирование для спасения мира», официальная учетная запись посвящена основам программирования, а также исследованиям и разработкам на стороне сервера, вы будете получать новые статьи как можно скорее~

Оригинал не так просто, много поддержки ~ спасибо!