GO语言模拟C++封装,继承,多态

不携带MAP结构

go 复制代码
package main

import "fmt"

// ==========================
// 1. 基类(父类):Animal
// ==========================

// Animal 定义一个动物基类
// 小写字段:私有(包外无法访问,实现封装)
type Animal struct {
	name string // 动物名称
	age  int    // 年龄
}

// NewAnimal 基类构造函数(推荐写法)
func NewAnimal(name string, age int) *Animal {
	return &Animal{
		name: name,
		age:  age,
	}
}

// Speak 父类方法(可被重写)
func (a *Animal) Speak() {
	fmt.Printf("[Animal] %s 发出了声音\n", a.name)
}

// GetName Name getter(访问私有字段)
func (a *Animal) GetName() string {
	return a.name
}

// GetAge Age getter
func (a *Animal) GetAge() int {
	return a.age
}

// SetAge 设置年龄(封装私有字段修改)
func (a *Animal) SetAge(age int) {
	if age > 0 {
		a.age = age
	}
}

// ==========================
// 2. 子类:Dog(继承 Animal)
// ==========================

// Dog 子类:嵌套 Animal 实现继承
type Dog struct {
	Animal        // 匿名字段 = 继承(Go 推荐组合式继承)
	breed  string // 品种(独有属性)
}

// NewDog 子类构造函数
func NewDog(name string, age int, breed string) *Dog {
	return &Dog{
		Animal: *NewAnimal(name, age), // 调用父类构造
		breed:  breed,
	}
}

// Speak 重写父类方法(多态)
func (d *Dog) Speak() {
	// 如果想调用父类方法:d.Animal.Speak()
	fmt.Printf("[Dog] %s 汪汪叫!品种:%s\n", d.GetName(), d.breed)
}

// WagTail 子类独有方法
func (d *Dog) WagTail() {
	fmt.Printf("[Dog] %s 正在摇尾巴~\n", d.GetName())
}

// ==========================
// 3. 另一个子类:Cat(演示多态)
// ==========================
type Cat struct {
	Animal
	color string
}

func NewCat(name string, age int, color string) *Cat {
	return &Cat{
		Animal: *NewAnimal(name, age),
		color:  color,
	}
}

func (c *Cat) Speak() {
	fmt.Printf("[Cat] %s 喵喵叫!颜色:%s\n", c.GetName(), c.color)
}

// ==========================
// 4. 接口:定义多态规范
// ==========================
type AnimalSound interface {
	Speak() // 只要实现 Speak() 就算这个接口
}

// ==========================
// 主函数:使用类
// ==========================
func main() {
	fmt.Println("===== 1. 创建父类 =====")
	animal := NewAnimal("小生物", 2)
	animal.Speak()

	fmt.Println("\n===== 2. 创建子类 Dog =====")
	dog := NewDog("旺财", 3, "金毛")
	dog.Speak()   // 调用重写方法
	dog.WagTail() // 调用子类独有方法
	dog.SetAge(4) // 调用父类方法
	fmt.Println("修改后年龄:", dog.GetAge())

	fmt.Println("\n===== 3. 创建子类 Cat =====")
	cat := NewCat("咪咪", 2, "白色")
	cat.Speak()

	fmt.Println("\n===== 4. 多态调用(接口) =====")
	animals := []AnimalSound{dog, cat}
	for _, a := range animals {
		a.Speak() // 自动调用各自重写的方法
	}
}

携带MAP结构

go 复制代码
package main

import (
	"fmt"
	"sync"
)

// ==========================
// 1. 基础类:动物
// ==========================
type Animal struct {
	name string
	age  int
}

func NewAnimal(name string, age int) *Animal {
	return &Animal{name: name, age: age}
}

func (a *Animal) Speak() {
	fmt.Printf("【%s】 %d岁\n", a.name, a.age)
}

func (a *Animal) GetName() string { return a.name }

// ==========================
//  2. 核心:动物管理类
//     ✅ map 直接写在类里面
//     ✅ 锁也写在类里面
//     ✅ 全部私有,外部无法乱改
//
// ==========================
type AnimalManager struct {
	// 👇 map 是类的内部成员(完全封装)
	animalMap map[string]*Animal

	// 👇 锁也属于类(和 map 绑定)
	lock sync.RWMutex
}

// 构造函数:必须初始化 map
func NewAnimalManager() *AnimalManager {
	return &AnimalManager{
		animalMap: make(map[string]*Animal), // 类内部初始化
	}
}

// ------------------------------
// 类的方法:操作内部 map
// 外部只能通过方法调用
// ------------------------------
func (m *AnimalManager) Add(animal *Animal) {
	m.lock.Lock()
	defer m.lock.Unlock()
	m.animalMap[animal.GetName()] = animal
}

func (m *AnimalManager) Get(name string) *Animal {
	m.lock.RLock()
	defer m.lock.RUnlock()
	return m.animalMap[name]
}

func (m *AnimalManager) Delete(name string) {
	m.lock.Lock()
	defer m.lock.Unlock()
	delete(m.animalMap, name)
}

func (m *AnimalManager) ShowAll() {
	m.lock.RLock()
	defer m.lock.RUnlock()

	fmt.Println("\n==== 类内部 map 全部动物 ====")
	for _, animal := range m.animalMap {
		animal.Speak()
	}
}

// ==========================
// 主函数:使用这个类
// ==========================
func main() {
	// 1. 创建管理类(内部自带 map + 锁)
	manager := NewAnimalManager()

	// 2. 创建动物
	a1 := NewAnimal("旺财", 3)
	a2 := NewAnimal("咪咪", 2)
	a3 := NewAnimal("小鸟", 1)

	// 3. 交给类管理(存入类内部的 map)
	manager.Add(a1)
	manager.Add(a2)
	manager.Add(a3)

	// 4. 查看所有(遍历类内部 map)
	manager.ShowAll()

	// 5. 获取一个
	animal := manager.Get("旺财")
	if animal != nil {
		fmt.Println("\n找到:")
		animal.Speak()
	}

	// 6. 删除
	manager.Delete("小鸟")
	fmt.Println("\n删除后:")
	manager.ShowAll()
}
相关推荐
CheerWWW3 小时前
C++学习笔记——this关键字、对象生命周期(栈作用域)、智能指针、复制与拷贝构造函数
c++·笔记·学习
温天仁3 小时前
西门子PLC编程实践教程:工控工程案例学习
开发语言·学习·自动化·php
lsx2024063 小时前
Java 数组
开发语言
JosieBook3 小时前
【C#】VS中的 跨线程调试异常:CrossThreadMessagingException
开发语言·c#
爱滑雪的码农3 小时前
Java八:Character 类与string类
java·开发语言
csbysj20203 小时前
《C 标准库 - 参考手册》
开发语言
漫随流水3 小时前
c++编程:D进制的A+B(1022-PAT乙级)
数据结构·c++·算法
tankeven4 小时前
HJ159 没挡住洪水
c++·算法
APIshop4 小时前
京东关键词搜索接口完全指南
java·开发语言·数据库