公司网站友情链接怎么做副链,wordpress add to cart 不用ajax,wordpress themepath,wordpress文章半透明面向过程
所谓的面向过程就是#xff1a;强调的是步骤、过程、每一步都是自己亲自去实现的。
面向对象
所谓的面向对象其实就是找一个专门做这个事的人来做#xff0c;不用关心具体怎么实现的。 所以说#xff0c;面向过程强调的是过程#xff0c;步骤。而面向对象强调的…面向过程
所谓的面向过程就是强调的是步骤、过程、每一步都是自己亲自去实现的。
面向对象
所谓的面向对象其实就是找一个专门做这个事的人来做不用关心具体怎么实现的。 所以说面向过程强调的是过程步骤。而面向对象强调的是对象也就是干事的人。 在程序中可以通过属性和方法函数来描述类。属性就是特征方法函数就是行为。
面向对象编程好处
封装 继承 多态
继承
继承是一种类间关系描述一个类从另一个类获取成员信息的类间关系。 继承必定发生在两个类之间参与继承关系的双方称为父类和子类。 父类提供成员信息子类获取成员信息。 通过匿名字段来实现继承
package mainimport fmttype Student struct {//属性---成员//方法---函数Person //匿名字段只有类型没有成员的名字score float64
}type Teacher struct {Person //匿名字段只有类型没有成员的名字salary float64
}type Person struct {id intname stringage int
}func main() {var stu Student Student{Person{1, 张三, 18}, 98}fmt.Println(stu) //{{1 张三 18} 98}//部分初始化var stu1 Student Student{score: 90}fmt.Println(stu1) //{{0 0} 90}var stu2 Student Student{Person: Person{id: 101}} //{{101 0} 0}fmt.Println(stu2)
}成员操作
package mainimport fmttype Student struct {//属性---成员//方法---函数Person //匿名字段只有类型没有成员的名字score float64
}type Person struct {id intname stringage int
}func main() {var stu Student Student{Person{101, 张三, 18}, 98}var stu1 Student Student{Person{102, 李四, 18}, 80}//获取成员的值fmt.Println(stu.score) //98fmt.Println(stu1.score) //80fmt.Println(stu1.Person.id) //102 //比较麻烦fmt.Println(stu1.id) //102//修改成员的值stu.score 100fmt.Println(stu.score) //100}指针类型匿名字段
package mainimport fmttype Student struct {//属性---成员//方法---函数*Person //指针类型匿名字段score float64
}type Person struct {id intname stringage int
}func main() {var stu Student Student{Person{101, 张三, 18}, 98}fmt.Println(stu) //{0xc000054460 98} 父类输出的是结构体内存地址 只能使用成员操作了fmt.Println(stu.name) //张三
}多重继承—尽量不要写多重继承
package mainimport fmt// Student 学生继承person
type Student struct {//属性---成员//方法---函数Person //指针类型匿名字段score float64
}// Person 父类 person继承object
type Person struct {Object1name stringage int
}type Object1 struct {id int
}func main() {var stu Studentstu.age 18fmt.Println(stu.Person.age) //18stu.id 101fmt.Println(stu.Person.Object1.id)
}为结构体添加方法—封装
func (对象 结构体类型) 方法名 (参数列表)(返回值列表) {代码体}方法调用
对象名.方法
//不支持重载只要接收者类型不一样这个方法就算同名也是不同方法不会出现重复定义函数的错误
package mainimport fmt// Student
type Student struct {id intname stringage int
}// PrintShow 方法 s为接收者
func (s Student) PrintShow() {fmt.Println(s) //{101 ziye 18}
}func (s Student) EditInfo() {s.age 20
}func (s *Student) EditInfo1() {s.age 20
}
func main() {stu : Student{101, ziye, 18}//对象名.方法名 把stu中的值传给了sstu.PrintShow() //完成对方法的调用stu.EditInfo() //不是引用传递是值传递stu.PrintShow()//内部会进行转换stu.EditInfo1() //引用传递stu.PrintShow() //{101 ziye 20}
}注意事项
只要接收者类型不一样这个方法就算同名也是不同方法 接收者为指针类型
package mainimport fmt// Student
type Student struct {id intname stringage int
}type Teacher struct {id intname string
}func (s *Student) show() {fmt.Println(s)
}func (t *Teacher) show() { //把teacher内存地址给到这里fmt.Println(t)
}
func main() {//如果接收者类型不同即使方法的名字是相同的也是不同的方法stu : Student{101, ziye, 18}stu.show() //等价于(stu).show()teacher : Teacher{102, ziyeye}teacher.show()
}面向对象方法练习
定义一个学生类,有六个属性,分别为姓名、性别、年龄、语文、数学、英语成绩 定义两个方法
第一方法打招呼的方法介绍自己叫XX今年几岁了。是男同学还是女同学。
第二个方法计算总分与平均分的方法package mainimport fmt// Student
type StudentInfo struct {name string //姓名sex string //性别age int //年龄chinese float64 //语文math float64 //数学english float64 //英语
}// SayHello 打招呼
func (studentInfo *StudentInfo) SayHello(username string, userAge int, userSex string) {//初始化studentInfo.name usernamestudentInfo.age userAgestudentInfo.sex userSex//初始化后的值进行判断if studentInfo.sex ! 男 studentInfo.sex ! 女 {studentInfo.sex 男}if studentInfo.age 1 || studentInfo.age 100 {studentInfo.age 18}//打印输出结果fmt.Printf(我叫%s,年龄是%d,性别是%s\n, studentInfo.name, studentInfo.age, studentInfo.sex)
}// GetScore 计算平均分
func (studentInfo *StudentInfo) GetScore(chinese float64, math float64, english float64) {//初始化studentInfo.chinese chinesestudentInfo.math mathstudentInfo.english english//进行计算sum : studentInfo.chinese studentInfo.math studentInfo.english//打印输出结果fmt.Printf(我叫%s,总分%f,平均分%.2f\n, studentInfo.name, sum, sum/3)
}
func main() {var stu StudentInfostu.SayHello(ziye, 18, 女)stu.GetScore(98, 97, 95)
}方法继承
package mainimport fmt// Student
type Student struct {Personscore float64
}type Person struct {id intname string //姓名age int //年龄
}func (p *Person) PrintInfo() {fmt.Println(*p) //{101 张三 18}
}func main() {stu : Student{Person{101, 张三, 18}, 90}//子类可以调用父类的方法stu.PrintInfo()
}方法继承的练习
根据以下信息实现对应的继承关系
记者我叫张三 我的爱好是偷拍我的年龄是34我是一个男狗仔。
程序员我叫孙全我的年龄是23我是男生我的工作年限是 3年。 package mainimport fmt// Person 定义父类
type Person struct {name stringage intsex string
}// SetValue 给父类添加方法
func (p *Person) SetValue(userName string, userAge int, userSex string) {p.name userNamep.age userAgep.sex userSex
}// Rep 定义相应的子类 记者类
type Rep struct {PersonHobby string //爱好
}// Pro 程序员类
type Pro struct {PersonWorkYear int
}// RepSayHello 给子类添加相应的信息
func (r *Rep) RepSayHello(Hobby string) {r.Hobby Hobbyfmt.Printf(我叫%s 我的爱好是%s我的年龄是%d我是一个%s狗仔\n, r.name, r.Hobby, r.age, r.sex)
}// ProSayHello 给子类添加相应的信息
func (p *Pro) ProSayHello(workYear int) {p.WorkYear workYearfmt.Printf(我叫%s我的年龄是%d我是%s我的工作年限是 %d年\n, p.name, p.age, p.sex, p.WorkYear)
}
func main() {var rep Reprep.SetValue(ziye, 34, 男)rep.RepSayHello(偷拍)var pro Propro.SetValue(李四, 26, 男)pro.ProSayHello(3)}方法重写
就是子类(结构体)中的方法将父类中的相同名称的方法的功能重新给改写了 注意在调用时默认调用的是子类中的方法
package mainimport fmt// Person 定义父类
type Person struct {name stringage int
}func (p *Person) PrintInfo() {fmt.Println(这是父类中的方法)
}type Student struct {Personscore float64
}func (s *Student) PrintInfo() {fmt.Println(这是子类中的方法)
}func main() {var stu Studentstu.PrintInfo() //这是子类中的方法 如果父类中的方法名称与子类中的方法一致那么通过子类的对象调用的是子类中的方法方法重写stu.Person.PrintInfo() //这是父类中的方法 调用父类中的方法
}方法值与方法表达式
package mainimport fmt// Person 定义父类
type Person struct {name stringage int
}func (p *Person) PrintInfo() {fmt.Println(*p) //{ziye 18}
}func main() {per : Person{ziye, 18}per.PrintInfo()//方法值f : per.PrintInfofmt.Printf(%T\n, f) //func() 方法类型f() //{ziye 18}//方法表达式f1 : (*Person).PrintInfo //并没有指定一个对象 类名要和方法接收者类型保存一致f1(per) //{ziye 18} 方法表达式
}接口简介
接口就是一种规范与标准只是规定了要做哪些事情。具体怎么做接口是不管的。 接口把所有的具有共性的方法定义在一起任何其他类型只要实现了这些方法就是实 现了这个接口。
接口定义
type 接口名字 interface {
方法声明}
接口的声明
可以为结构体添加接口中的方法完成接口中方法实现
package mainimport fmt// Personer 接口的声明
type Personer interface {SayHello() //方法声明
}type Student struct {
}// SayHello 使用student完成SayHello
func (s *Student) SayHello() {fmt.Println(老师好)
}type Teacher struct {
}func (t *Teacher) SayHello() {fmt.Println(学生好)
}func main() {//对象名.方法名var stu Studentstu.SayHello() //老师好var teacher Teacherteacher.SayHello() //学生好//接口变量来调用,必须都实现接口中所声明的方法var person Personerperson stuperson.SayHello() //调用的是Student、实现的SayHello方法 老师好person teacherperson.SayHello() //学生好}多态的定义与实现
什么是多态
所谓多态指的是多种表现形式。 多态就是同一个接口使用不同的实例而执行不同操作
package mainimport fmttype Personer interface {SayHello()
}type Student struct {
}func (s *Student) SayHello() {fmt.Println(老师好)
}type Teacher struct {
}func (t *Teacher) SayHello() {fmt.Println(学生好)
}//实现多态
func WhoSayHi(personer Personer) {personer.SayHello()
}func main() {var stu Studentvar teacher TeacherWhoSayHi(stu)WhoSayHi(teacher)
}案例
用多态来模拟实现 将移动硬盘或者U盘插到电脑上进行读写数据
package mainimport fmttype Stroager interface {Read()Writer()
}// MDisk 移动硬盘
type MDisk struct {
}func (m *MDisk) Read() {fmt.Println(移动硬盘读取数据)
}func (m *MDisk) Writer() {fmt.Println(移动硬盘写入数据)
}// UDisk U盘
type UDisk struct {
}func (u *UDisk) Read() {fmt.Println(U盘读取数据)
}func (u *UDisk) Writer() {fmt.Println(U盘写入数据)
}// Computer 定义一个函数
func Computer(s Stroager) {s.Writer()s.Read()
}
func main() {var uds UDiskvar mds MDiskComputer(uds)Computer(mds)
}案例
使用面向对象方式实现一个计算器程序
案例实现一 package mainimport fmttype Object1 struct {
}func (o *Object1) GetResult(num1, num2 int, op string) int {//添加参数var result intswitch op {case :result num1 num2case -:result num1 - num2}return result
}func main() {var obj Object1result : obj.GetResult(8, 6, )fmt.Println(result)
}案例实现二
package mainimport fmt// 加法类
type Add struct {Object1
}func (add *Add) GetResult() int { //方法的实现要和接口中方法的声明保持一致return add.numA add.numB
}type Sub struct {Object1
}func (sub *Sub) GetResult() int {return sub.numA - sub.numB
}type Object1 struct {numA intnumB int
}type Resulter interface {GetResult() int //返回类型int
}func main() {add : Add{Object1{10, 8}}result : add.GetResult()fmt.Println(result)sub : Sub{Object1{10, 8}}result sub.GetResult()fmt.Println(result)
}案例实现三
package mainimport fmt// 加法类
type Add struct {Object1
}func (add *Add) GetResult() int { //方法的实现要和接口中方法的声明保持一致return add.numA add.numB
}type Sub struct {Object1
}func (sub *Sub) GetResult() int {return sub.numA - sub.numB
}type Object1 struct {numA intnumB int
}type Resulter interface {GetResult() int //返回类型int
}// OperatorFactory 对象创建问题
// 1:定义一个新的类
type OperatorFactory struct {
}// CreaeteOperator 创建一个方法在该方法中完成对象的创建----封装
func (o *OperatorFactory) CreaeteOperator(op string, numA, numB int) int {switch op {case :add : Add{Object1{numA, numB}}return OperatorWho(add)case -:sub : Sub{Object1{numA, numB}}return OperatorWho(sub)default:return 0}
}
// 多态
func OperatorWho(h Resulter) int {result : h.GetResult()return result
}
func main() {var operator OperatorFactorycreaeteOperator : operator.CreaeteOperator(, 20, 10)fmt.Println(creaeteOperator)
}接口的继承与转换
package mainimport fmttype Humaner interface {SayHello()
}// Personer 接口继承
type Personer interface {HumanerSay()
}
type Student struct {
}func (s *Student) SayHello() {fmt.Println(大家好)
}func (s *Student) Say() {fmt.Println(你好)
}func main() {var Stu Studentvar per Personerper Stuper.Say()per.SayHello() //可以调用所继承的接口中的方法//接口转换var h Humanerh perh.SayHello()//超集可以转换为子集反过来不可以//per h
}空接口定义与使用
var i interface{} //空接口
i 123
fmt.Println(i)空接口可以赋任意的类型切片s可以赋值各种类型的
var s []interface{} //空接口切片ss append(s, 123, abc, 23.12)for i : 0; i len(s); i {fmt.Println(s[i])}空接口(interface{})不包含任何的方法正因为如此所有的类型都实现了空接口因此空接口可以存储任意类型的数值
类型断言
通过类型断言可以判断空接口中存储的数据类型。 语法value, ok : m.(T) m:表空接口类型变量 T:是断言的类型 value: 变量m中的值。 ok: 布尔类型变量如果断言成功为true,否则为false
package mainimport fmtfunc main() {var i interface{}i 123value, ok : i.(int)if ok {fmt.Println(value)} else {fmt.Println(类型推断错误)}
}案例–空接口与类型断言综合应用
计算器完成数据校验
package mainimport fmt// 加法类
type Add struct {Object1
}func (add *Add) GetResult() int { //方法的实现要和接口中方法的声明保持一致return add.numA add.numB
}func (add *Add) SetData(data ...interface{}) bool {//对数据的个数进行校验var b bool trueif len(data) 2 || len(data) 1 {fmt.Println(参数个数错误)b false}value, ok : data[0].(int)if !ok {fmt.Println(第一个数类型错误)b false}value1, ok1 : data[1].(int)if !ok1 {fmt.Println(第二个数类型错误)b false}add.numA valueadd.numB value1//对传递过来的类型进行校验return b
}type Sub struct {Object1
}func (sub *Sub) GetResult() int {return sub.numA - sub.numB
}
func (sub *Sub) SetData(data ...interface{}) bool {//对数据的个数进行校验var b bool trueif len(data) 2 || len(data) 1 {fmt.Println(参数个数错误)b false}value, ok : data[0].(int)if !ok {fmt.Println(第一个数类型错误)b false}value1, ok1 : data[1].(int)if !ok1 {fmt.Println(第二个数类型错误)b false}sub.numA valuesub.numB value1//对传递过来的类型进行校验return b
}type Object1 struct {numA intnumB int
}type Resulter interface {GetResult() int //返回类型intSetData(data ...interface{}) bool //完成参数运算的数据的类型校验
}// OperatorFactory 对象创建问题
// 1:定义一个新的类
type OperatorFactory struct {
}// CreaeteOperator 创建一个方法在该方法中完成对象的创建----封装
func (o *OperatorFactory) CreaeteOperator(op string) Resulter {switch op {case :add : new(Add) //返回*addreturn addcase -:sub : new(Sub) //创建Sub 开辟相应的存储空间return subdefault:return nil}
}// 多态
func OperatorWho(h Resulter) int {result : h.GetResult()return result
}
func main() {var operator OperatorFactorycreaeteOperator : operator.CreaeteOperator(-) //拿到对象setData : creaeteOperator.SetData(30, 10)if setData {who : OperatorWho(creaeteOperator)fmt.Println(who)}}