一、面向对象的三大特征
封装和多态的特性
二、封装
封装就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有被授权的操作(方法),才能对字段进行操作。
1)
隐藏实现细节
2)
提可以对
数据进行验证
,保证安全合理
三、封装的实现步骤
package main
import "fmt"
// 结构体大写可以被外包访问
type person struct {
Name string // 大写可以外包访问
age int // 小写外包不可访问
sal float64
}
func NewPerson(name string) *person{
return &person{Name: name,}
}
func (p *person) GetAge() int{
return p.age
}
func (p *person) SetAge(age int) {
if(age >0 && age < 120){
p.age = age
}else{
fmt.Println("年龄不符合范围")
}
}
func (p *person) GetSal() float64{
return p.sal
}
func (p *person) SetSal(sal float64){
if(sal >= 3000 && sal <=30000){
p.sal = sal
}else{
fmt.Println("薪水范围不正确")
}
}
/**
封装快速入门案例
*/
func main() {
//p := model.NewPerson("smith") // 访问外包
p := NewPerson("smith") // 访问本包
p.SetAge(86)
p.SetSal(3012.28)
fmt.Println(p.Name)
fmt.Println(p.GetAge())
fmt.Println(p.GetSal())
}
特别说明
:在
Golang
开发中并没有特别强调封装,这点并不像
Java.
所以提醒学过
java
的朋友,
不用总是用
java
的语法特性来看待
Golang, Golang
本身对面向对象的特性做了简化的
四、继承
1、介绍
简单理解:就是结构体的嵌套,达到复用代码的目的
2、基本语法
type Goods struct{ //父类
Name string
Price int
}
type Book struct{ //子类
Goods //嵌套匿名结构体
Writer string
}
3、具体说明
1)
结构体可以
使用嵌套匿名结构体所有的字段和方法
,即:首字母大写或者小写的字段、方法,
都可以使用。(不夸包,夸包必须大写)
type A struct {
Name string
age int
}
func (a *A) SayOk() {
fmt.Println("A sayok", a.Name)
}
type B struct {
A
}
func main() {
var b B
b.A.Name = "tome"
b.A.age = 19
b.A.SayOk()
b.SayOk() // 可以简略
fmt.Println(b.Name) // 就近访问,如果B结构体有Name则访问的是B结构体里的Name
}
2)
匿名结构体字段访问可以简化
3)
当
结构体
和
匿名结构体
有相同的字段或者方法时,
就近访问原则访问
,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分
4)
结构体嵌入两个
(
或多个
)
匿名结构体,如
两个匿名结构体有相同的字段和方法
(
同时结构体本身
没有同名的字段和方法
)
,在访问时,就必须明确指定匿名结构体名字,否则编译报错。
type A struct{
Name string
age int}
type B struct{
Name string
Score float64}
type c struct{
A
B
//name string
}
func main(){
var c C
//如果c没有Name字段,而A和B有Name,这时就必须通过指定匿名结构体名字来区分
//所以,c.Name就会报编译错误,这个规则对方法也是一样的
c.A.Name = "tom"
fmt.Println(c)}
5) 如果一个 struct 嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合
的结构体的字段或方法时,必须带上结构体的名字
type A struct{
Name string
Age int}
type c struct{
a A //有名结构体 组合关系
}
func main(){
//如果C中是一个有名结构体,则访问有名结构体的字段时,就必须带上有名结构体的名字
//比如 c.A.Name
var c C
c.Name = "jack" //报错
c.A.Name = "jack" //正确
}
6) 嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值
package mainimport "fmt"
type Goods struct{ //商品
Name string
Price float64
}
type Brand struct{ //品牌
Name string
Address string}
type TV struct{ //电视剧
Goods
Brand}
func main(){
tv1 := TV{Goods{"电视剧001",5000.99},Brand{"海尔","青岛"},}
tv2 := TV{Goods{Name:"电视剧002",Price:5000.99},
Brand{Name:"海尔",Address:"青岛"},
}
fmt.Println("tv1",tv1)
fmt.Println("tv2",tv2)
}
五、面向对象编程-多态
变量
(
实例
)
具有多种形态。面向对象的第三大特征,在
Go
语言,多态特征是通过接口实现的。可
以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。
usb案例
package main
import "fmt"
// 接口
type Usb interface {
Start()
Stop()
}
// 手机
type Phone struct {
}
func (p Phone) Start() {
fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
fmt.Println("手机停止工作。。。")
}
// 相机
type Camera struct {
}
func (c Camera) Start() {
fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop() {
fmt.Println("相机停止工作。。。")
}
// 电脑
type Computer struct {
}
func (c Computer) Working(usb Usb) { //usb 变量会根据传入的实参,来判断到底是 Phone,还是 Camera
//通过 usb 接口变量来调用 Start 和 Stop 方法
usb.Start()
usb.Stop()
}
func main() {
//先创建结构体变量
computer := Computer{}
phone := Phone{}
camera := Camera{}
//关键点
computer.Working(phone)
computer.Working(camera)
}