🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## **面向对象编程三大特性\-封装** #### **封装介绍** 封装(encapsulation)就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行操作 封装的理解和好处 1)隐藏实现细节 2)提可以对数据进行验证,保证安全合理(Age) #### **封装的实现步骤** 1)将结构体、字段(属性)的首字母小写(不能导出了,其它包不能使用,类似private) 2)给结构体所在包提供一个工厂模式的函数,首字母大写。类似一个构造函数 3)提供一个首字母大写的Set方法(类似其它语言的public),用于对属性判断并赋值 ``` func(var结构体类型名)SetXxx(参数列表)(返回值列表){ //加入数据验证的业务逻辑 var.字段=参数 } ``` 4)提供一个首字母大写的Get方法(类似其它语言的public),用于获取属性的值 ``` func(var结构体类型名)GetXxx(){ return var.age; } ``` 特别说明:在Golang开发中并没有特别强调封装,这点并不像Java.所以提醒学过java的朋友, 不用总是用java的语法特性来看待Golang,Golang本身对面向对象的特性做了简化的. #### **快速入门案例** 请大家看一个程序(person.go),不能随便查看人的年龄,工资等隐私,并对输入的年龄进行合理的验证。设计:model包(person.go)main包(main.go调用Person结构体) model/person.go ![](https://img.kancloud.cn/b8/be/b8be14e1b5b9142c276ab43ecac51ca3_1065x653.png) ![](https://img.kancloud.cn/70/7a/707a6d97633ecd0dc1fab63447724c09_1007x579.png) main/main.go ![](https://img.kancloud.cn/a1/a7/a1a75f3c03ba66a15bcbcb12e4c7f967_1007x478.png) ## **面向对象编程三大特性-继承** 1)字段和方法几乎相同了相同但是我们却写了相同的代码,代码复用性不强 2)出现代码冗余,而且代码不利于维护,同时也不利于功能的扩展。 3)解决方法-通过继承方式来解决 ![](https://img.kancloud.cn/16/8e/168e6674b80460e63505df844c07b21f_706x383.png) 也就是说:在Golang中,如果一个struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。 **嵌套匿名结构体的基本语法** ``` typeGoodsstruct{ Namestring Priceint } typeBookstruct{ Goods//这里就是嵌套匿名结构体Goods Writerstring } ``` **继承给编程带来的便利** 1)代码的复用性提高了 2)代码的扩展性和维护性提高了 **继承的深入讨论** 1)结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。【举例说明】 ![](https://img.kancloud.cn/28/7c/287c37b192af85412dd5f95b8f1491ee_787x671.png) 2)匿名结构体字段访问可以简化,如图 ![](https://img.kancloud.cn/06/9d/069d47e33b6818258c1563f36a70a975_788x453.png) 对上面的代码小结 (1)当我们直接通过b访问字段或方法时,其执行流程如下比如b.Name (2)编译器会先看b对应的类型有没有Name,如果有,则直接调用B类型的Name字段 (3)如果没有就去看B中嵌入的匿名结构体A有没有声明Name字段,如果有就调用,如果没有继续查找..如果都找不到就报错. 3)当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分【举例说明】 ![](https://img.kancloud.cn/0f/d5/0fd5f947a18a191ce7de64ac4a181303_557x270.png) 4)结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。【举例说明】 ![](https://img.kancloud.cn/c2/2e/c22e06d9218c256798bf3120bfd9e6ff_837x500.png) 5)如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字 ![](https://img.kancloud.cn/ac/77/ac77445006541e4278cc856e5c3cda16_652x224.png) 6)嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值 ![](https://img.kancloud.cn/9a/da/9ada469e2a67282980c0c65b4ab56f09_459x745.png) **结构体的匿名字段是基本数据类型,如何访问,下面代码输出什么** ![](https://img.kancloud.cn/5b/f7/5bf7aa9d1b27c1ae253379a2e7263adf_534x591.png) 说明 1)如果一个结构体有int类型的匿名字段,就不能第二个。 2)如果需要有多个int的字段,则必须给int字段指定名字 ### **多重继承说明** 如一个struct嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。 ![](https://img.kancloud.cn/3b/fa/3bfa2002c7ea8dd520427d903d18356c_617x383.png) **多重继承细节说明** 1)如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。【案例演示】 ![](https://img.kancloud.cn/99/c1/99c1b9f1da881d031bf5cd740e13ff62_743x107.png) 2)为了保证代码的简洁性,建议大家尽量不使用多重继承