Programación orientada a objetos de Golang

Programación orientada a objetos de Golang

* Catálogo
00 Instrucciones de programación orientada a objetos en lenguaje Golang
01 Campos, atributos
02 Método
03 Programación orientada a objetos
04 Modo de fábrica
05 Ideas de programación orientada a objetos *

00 Instrucciones de programación orientadas a objetos en lenguaje Golang

  • Golang también admite la programación orientada a objetos (POO), pero es diferente de la programación orientada a objetos tradicional y no es un lenguaje orientado a objetos puro. Por lo tanto, es más exacto decir que Golang admite funciones de programación orientadas a objetos.

  • Golang no tiene clase. La estructura del lenguaje Go tiene el mismo estado que la clase de otros lenguajes de programación. Puedes entender que Golang implementa funciones de programación orientada a objetos basadas en struct.

  • La programación orientada a objetos de Golang es muy concisa, elimina la herencia del lenguaje OOP tradicional, la sobrecarga de métodos, el constructor y destructor, oculta este puntero, etc.

  • Golang todavía tiene las características de herencia, encapsulación y polimorfismo de la programación orientada a objetos, pero la implementación es diferente de otros lenguajes de programación orientada a objetos, como la herencia: Golang no tiene la palabra clave extiende y la herencia se logra a través de campos anónimos.

  • Golang orientado a objetos (OOP) es muy elegante, la OOP en sí es parte del sistema de tipos de lenguaje (sistema de tipos), a través de la asociación de interfaz (interfaz), acoplamiento bajo y muy flexible. En otras palabras, la programación orientada a la interfaz es una característica muy importante en Golang.

La diferencia y conexión entre estructura y variable de estructura (instancia)

  • La estructura es un tipo de datos personalizado, que representa una clase de cosas.

  • Las variables de estructura (instancias) son concretas, reales y representan una variable concreta

Cómo declarar una estructura

Tipo de nombre de la estructura struct { 
    tipo campo1 
    tipo campo2 
    ... 
}

Definir la estructura del perro

type Dog struct { 
    Name string 
    Age int64 
    Color string}

01 campo, atributo

  • Desde el punto de vista del concepto o del nombre: estructura campo = atributo = campo

  • El campo es un componente de la estructura, generalmente un tipo de datos básico, una matriz, pero también un tipo de referencia.

Notas y detalles

  • La sintaxis de la declaración de campo es la misma que la de las variables, ejemplo: nombre de campo tipo de campo

  • El tipo de campo puede ser: tipo básico, matriz o tipo de referencia

  • Después de crear una variable de estructura, si no se asigna ningún valor al campo, corresponde a un valor cero (el valor predeterminado), y las reglas son las mismas que las anteriores:

    • Use slice para asegurarse: p1.slice1 = make ([] int, 10)

    • Use map para asegurarse: p1.map1 = make (map [string] string)

    • El tipo booleano es falso, el valor es 0 y la cadena es ""

    • El valor predeterminado del tipo de matriz está relacionado con su tipo de elemento, por ejemplo, score [3] int es [0,0, 0]

    • El valor cero del puntero, el segmento y el mapa son todos nulos, es decir, todavía no se ha asignado ningún espacio.

  • Los campos de las diferentes variables de estructura son independientes y no se afectan entre sí, y la estructura es un tipo de valor.

Crear variables de estructura y campos de estructura de acceso

var dd Dogvar dd Dog = Person {"小花", 4, "red"} var dd * Dog = new (Dog) 
(* dd) .Name = "小花" dd.Name = "小花" var dd * Dog = & Dog {"小花", 4, "red"} var dd * Dog = & Dog {} 
(* dd) .Name = "小花" dd.Name = "小花"

Descripción:

1) 
Los métodos tercero y cuarto devuelven punteros de estructura. 2) 
La forma estándar para que los punteros de estructura accedan a los campos debería ser: (* Puntero de estructura). Nombre del campo, 
como (* persona) .Name = "tom" 3) Pero go ha hecho una simplificación y 
también admite punteros de estructura. Campo Nombre, 
como person.Name = "tom". 3) La 
capa inferior del compilador go ha convertido person.Name (* person) .Name.

Precauciones y detalles para el uso de estructuras

  • Todos los campos de la estructura son continuos en la memoria.

  • La estructura es un tipo definido por separado por el usuario, y debe tener exactamente los mismos campos (nombre, número y tipo) cuando se convierte con otros tipos.

  • La estructura se redefine por tipo (equivalente a aliasing). Golang considera que es un nuevo tipo de datos, pero puede verse obligado a transferirse entre sí.

  • Se puede escribir una etiqueta en cada campo de la estructura y la etiqueta se puede obtener a través del mecanismo de reflexión.Los escenarios de uso comunes son la serialización y la deserialización.

02 método

El método en Golang funciona con el tipo de datos especificado (es decir, vinculado al tipo de datos especificado), por lo que los tipos personalizados pueden tener métodos, no solo estructura.

Declaración de método y llamada

escriba A struct { 
    Num int} func (a A) test () { 
    fmt.Println (a.Num) 
}

Descripción

  • func (a A) test (El libro indica que la estructura A tiene un método, el método se llama test

  • (aA) refleja que el método de prueba está vinculado al tipo A

paquete mainimport ("fmt") type Person struct { 
    Name string} func (P Person) test ({ 
    fmt.Println ("test ((name =", p.Name) func main () {var p Personp.Name = " tom " 
    p.test () // Método de llamada 
} 

// 1) El método de prueba está vinculado al tipo Person 
// 2) El método de prueba solo puede ser llamado por una variable del tipo Person, y no puede ser llamado directamente, tampoco se pueden usar otros tipos de variables Para llamar a 
// func (p Person) test () .... p representa qué variable de Person se llama, y ​​esta p es una copia de ella, que a menudo es similar a pasar una función. 
// 4) El nombre p lo especifica el programador y no es fijo. Por ejemplo, se puede cambiar a person

El principio de la llamada al método y el mecanismo de transferencia de parámetros.

  • Cuando se llama a un método a través de una variable, el mecanismo de llamada es el mismo que el de una función

  • La diferencia es que cuando la variable llama al método, la variable en sí también se pasará al método como un parámetro (si la variable es un tipo de valor, entonces el valor se copia, si la variable es un tipo de referencia, entonces la dirección se copia)

Notas y detalles del método

  • El tipo de estructura es un tipo de valor. En la llamada al método se cumple con el mecanismo de transferencia del tipo de valor, que es el método de transferencia de copia de valor.

  • Si el programador desea modificar el valor de la variable de estructura en el método, puede ser manejado por el puntero de estructura.

  • Los métodos en Golang actúan sobre el tipo de datos especificado (es decir, se vinculan al tipo de datos especificado), por lo que los tipos personalizados pueden tener métodos, no solo estructuras, como int, float32, etc.pueden tener métodos

  • Las reglas para controlar el alcance de acceso de los métodos son las mismas que las de las funciones. La primera letra del nombre del método está en minúsculas y solo se puede acceder a ella en este paquete. La primera letra del método está en mayúscula y se puede acceder a ella en este paquete y en otros paquetes.

  • Si un tipo implementa el método String (), entonces fimt.PrintIn llamará a String () de esta variable para la salida de forma predeterminada

Copia de valor y copia de dirección en encuadernación de tipo

  • Independientemente del formulario de llamada, la verdadera decisión es la copia del valor o la copia de la dirección, según el tipo al que esté vinculado el método.

  • Si es un tipo de valor de suma, como (p Persona), es una copia de valor, y si es un tipo de puntero, como (p * Persona), es una copia de dirección.

  • La copia de dirección puede modificar los atributos en el tipo de enlace.

03 Programación orientada a objetos

paso

  • Declarar (definir) la estructura, determinar el nombre de la estructura

  • Escribe los campos de la estructura

  • Método de estructura de escritura

Especificar valores de campo al crear variables de estructura

var stu1 = Stu {"小 明", 19} var stu3 = Stu { 
    Nombre: "jack", 
    Edad: 20, 
} var stu5 * stu = & stu {"小王", 29} var stu7 = & stu { 
    Nombre: "小Lee ", 
    Edad: 49, 
}

04 Modo de fábrica

La estructura de Golang no tiene constructor, y el patrón de fábrica generalmente se puede usar para resolver este problema.

La primera letra S del Student de la estructura está en mayúscula. Si queremos crear una instancia del Student en otros paquetes (como el paquete principal) e importar el paquete modelo, podemos crear directamente las variables (instancias) del Estructura estudiantil. Pero aquí viene el problema: si la primera letra está en minúsculas, como type student struct, no funcionará. ¿Cómo hacer? Modelo de fábrica a resolver.

Utilice el patrón de fábrica para crear instancias de estructura (variables) en todos los paquetes

escriba student struct { 
Name stringscore float64) 


fune Newstudent (n string, s float64) * student {return & student { 
    Name: n, 
    Score: s, 
}

05 Ideas de programación orientada a objetos

abstracto

Cuando definimos una estructura antes, en realidad extraemos los atributos (campos) y comportamientos (métodos) comunes de una clase de cosas para formar un modelo físico (estructura). Este método de estudiar un problema se llama abstracción.

Encapsulamiento

Golang todavía tiene las características de herencia, encapsulación y polimorfismo de la programación orientada a objetos, pero la forma en que se implementa es diferente de otros lenguajes de programación orientada a objetos.

La encapsulación consiste en encapsular los campos abstraídos y las operaciones en los campos.Los datos están protegidos internamente y otros paquetes del programa solo pueden operar en los campos a través de operaciones autorizadas (métodos).

Comprensión y beneficios de la encapsulación

  • Ocultar detalles de implementación

  • Los datos se pueden verificar para garantizar la seguridad y la razonabilidad (edad)

Cómo reflejar la encapsulación

  • Encapsular los atributos en la estructura

  • A través del método, el paquete se da cuenta de la encapsulación.

Pasos para la realización de la encapsulación

  • Ponga en minúscula la primera letra de la estructura y el campo (atributo) (no se puede exportar, no se pueden usar otros paquetes, similar al privado)

  • Proporcione una función de modo de fábrica para el paquete donde se encuentra la estructura, con la primera letra en mayúscula. Similar a un constructor

  • Proporcionar un método de conjunto con letras mayúsculas iniciales (similar al público en otros idiomas) para juzgar y asignar atributos

  • Proporcione un método Get con letras mayúsculas iniciales (similar al público en otros idiomas) para obtener atributos

Nota especial:

En el desarrollo de Golang, no hay un énfasis especial en la encapsulación. Esto no es como Java. El propio Golang simplifica las características orientadas a objetos.

type person struct { 
    Name string 
    age int} func NewPerson (name string) * person {return & person { 
        Name: name, 
    } 
} func (p * person) setAge (age int) {if age> 0 && age <150 { 
        p. age = age 
    } else { 
        fmt.Print1n ("年龄 范围 不 正确 ..") 
    } 
} func (p * person) GetAge () int {return p.age 
}

heredar

La herencia puede resolver la reutilización del código y acercar nuestra programación al pensamiento humano.

Cuando varias estructuras tienen las mismas propiedades (campos) y métodos, la estructura se puede abstraer de estas estructuras y estas mismas propiedades y métodos se pueden definir en la estructura.

Sintaxis básica de estructuras anónimas anidadas

tipo 
    Estructura de bienes { Nombre stringPrice int} tipo Estructura de libro { 
    Cadena de escritor de 
    bienes         }

Discusión en profundidad de la herencia

  • La estructura puede utilizar todos los campos y métodos de la estructura anónima anidada, es decir, se pueden utilizar los campos y métodos con la primera letra en mayúscula o minúscula.

  • El acceso al campo de la estructura anónima se puede simplificar.

bAName = "tom" bAage = 19b.A.Sayok () 
bAhello () 


b.Name = "smith" b.age = 20b.sayok () 
b.hello ()
  • Cuando la estructura y la estructura anónima tienen los mismos campos o métodos, el compilador utiliza el principio de acceso más cercano. Si desea acceder a los campos y métodos de la estructura anónima, puede distinguirlos por el nombre de la estructura anónima.

edad = 19
  • La estructura incrusta dos (o más) estructuras anónimas. Por ejemplo, dos estructuras anónimas tienen los mismos campos y métodos (al mismo tiempo, la estructura en sí no tiene campos y métodos con el mismo nombre). Al acceder, debe explícitamente especifique el nombre de la estructura anónima; de lo contrario, compile un error.

  • Si una estructura está anidada con una estructura nombrada, este modo es una combinación, si es una relación de combinación, entonces al acceder a los campos o métodos de la estructura combinada, debe traer el nombre de la estructura.

tipo D estructura i 
    aA     
}
  • Una vez anidada la estructura anónima, también puede especificar directamente el valor de cada campo de estructura anónima al crear una variable de estructura (instancia)

tipo 
    Estructura de bienes { 
    Nombre cadena Precio float64} tipo Marca estructura { 
    Cadena de nombre 
    Dirección cadena} tipo TV estructura { 
    Mercancía 
    Marca 
} tipo TV2 estructura { 
    * Bienes 
    * Marca 
} 

tv: = TV {Bienes {"电视 001", 900.99}, Marca {"Haier", "Shandong"},} 
tv2: = TV { 
    Productos { 
        Precio: 88,99, 
        Nombre: "电视 ee2" 
    }, 
    Marca { 
        Nombre: "Sharp", 
        Dirección: "Beijing", 
    }, 
} 


tv3: = TV2 {& Goodsf {"TV03", 7000.99}, & Brand {"Skyworth", "Henan"}} 
tv4: = TV2 { 
    &Productos { 
        Nombre: "TV 4", 
        Precio: 9eee.99,
    } 
    & Marca { 
        Nombre: "Changhong", 
        Dirección: "Sichuan", 
    }, 
}

Herencia múltiple

Si una estructura está anidada con múltiples estructuras anónimas, entonces la estructura puede acceder directamente a los campos y métodos de la estructura anónima anidada, obteniendo así una herencia múltiple.

Para garantizar la simplicidad del código, se recomienda evitar el uso de herencia múltiple tanto como sea posible

interfaz

El polimorfismo en Golang se refleja principalmente a través de interfaces

El tipo de interfaz puede definir un conjunto de métodos, pero no es necesario implementarlos. Y la interfaz no puede contener variables. Cuando se va a utilizar un determinado tipo personalizado, estos métodos se escriben (implementan) de acuerdo con la situación específica.

escriba interfaz USB { 
    
    Start () 
    Stop () 
}
  • Todos los métodos de la interfaz no tienen cuerpo de método, es decir, los métodos de la interfaz son métodos que no están implementados. La interfaz encarna la idea de polimorfismo y alta cohesión y bajo acoplamiento del diseño del programa.

  • La interfaz en Golang no necesita implementarse explícitamente. Siempre que una variable contenga todos los métodos del tipo de interfaz, esta variable implementa la interfaz. Por lo tanto, no existe una palabra clave como implementar en Golang

Notas y detalles

  • La interfaz en sí no puede crear una instancia, pero puede apuntar a una variable (instancia) de un tipo personalizado que implementa la interfaz.

  • Todos los métodos de la interfaz no tienen cuerpo de método, es decir, todos son métodos que no están implementados.

  • En Golang, un tipo personalizado necesita implementar todos los métodos de una interfaz, decimos que este tipo personalizado implementa la interfaz.

  • Un tipo personalizado solo puede asignar una instancia (variable) del tipo personalizado al tipo de interfaz si implementa una determinada interfaz

  • Siempre que sea un tipo de datos personalizado, puede implementar una interfaz, no solo un tipo de estructura.

  • Un tipo personalizado puede implementar múltiples interfaces

  • No puede haber ninguna variable en la interfaz de Golang

  • Una interfaz (como la interfaz A) puede heredar muchas otras interfaces (como las interfaces B y C). En este momento, si desea implementar la interfaz A, también debe implementar todos los métodos de las interfaces B y C.

  • El tipo de interfaz es un puntero (tipo de referencia) de forma predeterminada. Si se usa sin inicializar la interfaz, generará nil

  • La interfaz de interfaz vacía} no tiene métodos, por lo que todos los tipos implementan la interfaz vacía, es decir, podemos asignar cualquier variable a la interfaz vacía.

La diferencia entre herencia e interfaz

  • Cuando la estructura A hereda la estructura B, entonces la estructura A hereda automáticamente los campos y métodos de la estructura B y se puede utilizar directamente

  • Cuando la estructura A necesita expandir sus funciones y no quiere destruir la relación de herencia, se puede implementar una interfaz, por lo que podemos pensar que la implementación de la interfaz es un complemento al mecanismo de herencia.

La implementación de una interfaz puede verse como un complemento de la herencia

La interfaz y la herencia resuelven diferentes problemas

  • El valor de la herencia es principalmente resolver la reutilización y mantenibilidad del código.

  • El valor de la interfaz radica principalmente en: diseñar, diseñar varias especificaciones (métodos) y permitir que otros tipos personalizados implementen estos métodos.

  • La interfaz es más flexible que la herencia

  • Las interfaces son más flexibles que la herencia,

    • La herencia es para satisfacer la relación es-a

    • La interfaz solo necesita satisfacer la relación like-a

  • La interfaz logra el desacoplamiento del código hasta cierto punto

Polimorfismo

Las variables (instancias) tienen muchas formas. La tercera característica principal del polimorfismo orientado a objetos, en el lenguaje Go, se logra a través de interfaces. Se pueden llamar diferentes implementaciones de acuerdo con una interfaz unificada. En este momento, la variable de interfaz toma una forma diferente.

  • Parámetro polimórfico

  • Matriz polimórfica

Aserción de tipo

Aserción de tipo, debido a que la interfaz es un tipo general, no conoce el tipo específico, si desea convertir a un tipo específico, debe usar la aserción de tipo

var x interface {} var b2 float32 = 1.1x = b2     
        
y: = x. (float32) 
fmt.Printf ("El tipo de y es el valor de la lámpara =% v", y, y)

Al hacer una afirmación de tipo, si el tipo no coincide, notificará un pánico. Por lo tanto, cuando haga una afirmación de tipo, asegúrese de que la interfaz vacía original apunte al tipo afirmado.

var x interface {} var b2 float32 = 2.1 x = b2if y, ok: = x. (float32); ok { 
    fmt.Println ("convertir 
    exitosamente ") fmt.Printf ("El tipo de y es% T y el valor is =% v ", y, y) 
} else { 
    fmt.Print1n (" convertir fai1 ") 
} 
fmt.Print1n (" Continuar ejecución ... ")

 

 

Supongo que te gusta

Origin blog.csdn.net/ThomasYC/article/details/115214890
Recomendado
Clasificación