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()
}
相关推荐
jerryinwuhan4 小时前
基于各城市站点流量的复合功能比较
开发语言·php
迈巴赫车主4 小时前
Java基础:list、set、map一遍过
java·开发语言
智者知已应修善业5 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
南 阳6 小时前
Python从入门到精通day66
开发语言·python
十八旬7 小时前
快速安装ClaudeCode完整指南
开发语言·windows·python·claude
前进的李工7 小时前
EXPLAIN输出格式全解析:JSON、TREE与可视化
开发语言·数据库·mysql·性能优化·explain
Byron Loong8 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
独隅8 小时前
CodeX + Visual Studio Code 联动的全面指南
开发语言·php
坚果派·白晓明8 小时前
【鸿蒙PC三方库移植适配框架解读系列】第一篇:Lycium C/C++ 三方库适配 — 概述与环境配置
c语言·开发语言·c++·harmonyos·开源鸿蒙·三方库·c/c++三方库
爱吃小白兔的猫8 小时前
LPA算法详解:一种近线性时间的图社区发现方法
开发语言·php