闭包实现类
2023/8/2About 7 min
闭包实现类
你是否曾经想过,不用类也能封装数据和方法?这篇文章将带你走进闭包的奇妙世界,展示如何用闭包来实现这一点。通过一个有趣的代码示例,你将看到闭包是如何捕获变量并提供类似类的功能的。准备好了吗?让我们开始这段有趣的旅程吧!
cpp
#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <memory>
using namespace std;
// 1. 封装 (Encapsulation) - 状态_x被封装在闭包中
auto createCounter(int x) {
int* _x = new int(x);
auto toString = [_x]() -> string { return "Counter x: " + to_string(*_x); };
auto add = [_x]() { (*_x)++; };
auto remove = [_x]() { delete _x; };
struct Counter {
function<string()> toString;
function<void()> add;
function<void()> remove;
};
return Counter{toString, add, remove};
}
// 2. 抽象 (Abstraction) - 定义一个“形状”的抽象接口
struct Shape {
function<string()> toString;
function<double()> area;
function<void()> draw;
};
// 3. 继承 (Inheritance) 和 多态 (Polymorphism)
// 基“类”工厂函数:ShapeBase
auto ShapeBase(const string& name, double value) {
string* _name = new string(name);
double* _value = new double(value);
// 基类的公共方法
auto baseToString = [_name]() -> string { return "Shape: " + * _name; };
auto baseGetValue = [_value]() -> double { return * _value; };
auto baseRemove = [_name, _value]() {
delete _name;
delete _value;
};
struct Base {
function<string()> toString;
function<double()> getValue;
function<void()> remove;
};
return Base{baseToString, baseGetValue, baseRemove};
}
// 派生“类”1: Circle,继承自ShapeBase,并实现area和draw
auto createCircle(const string& name, double radius) {
// 组合:捕获基类实例,模拟继承
auto base = ShapeBase(name, radius);
auto area = [base]() -> double {
double r = base.getValue();
return 3.14159 * r * r;
};
auto draw = [base, area]() {
cout << "Drawing Circle: " << base.toString() << ", area: " << area() << endl;
};
// 重写toString,添加派生类信息
auto toString = [base]() -> string {
return base.toString() + " (Circle)";
};
auto remove = [base]() { base.remove(); };
return Shape{toString, area, draw};
}
// 派生“类”2: Square,继承自相同的抽象接口,但不同实现
auto createSquare(const string& name, double side) {
auto base = ShapeBase(name, side);
auto area = [base]() -> double {
double s = base.getValue();
return s * s;
};
auto draw = [base, area]() {
cout << "Drawing Square: " << base.toString() << ", area: " << area() << endl;
};
auto toString = [base]() -> string {
return base.toString() + " (Square)";
};
auto remove = [base]() { base.remove(); };
return Shape{toString, area, draw};
}
int main() {
cout << "=== 1. 封装示例 ===" << endl;
auto counter = createCounter(5);
cout << counter.toString() << endl; // x: 5
counter.add();
cout << counter.toString() << endl; // x: 6
counter.remove();
cout << "\n=== 2. 抽象、继承与多态示例 ===" << endl;
// 多态:将不同的派生类对象统一存放在基类抽象接口的容器中
vector<Shape> shapes;
shapes.push_back(createCircle("MyCircle", 3.0));
shapes.push_back(createSquare("MySquare", 2.5));
for (auto& shape : shapes) {
// 同一接口,不同行为
cout << shape.toString() << ", Area: " << shape.area() << endl;
shape.draw(); // 多态调用
cout << "---" << endl;
}
// 释放资源
for (auto& shape : shapes) {
// 通常remove需要被调用,这里演示,实际需注意生命周期管理
// shape.remove(); // 此例中shape持有base的副本,base.remove会释放资源
// 更安全的做法是使用智能指针,但示例为展示闭包机制,暂不引入
}
return 0;
}c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// === 1. 封装(Encapsulation): Counter "类" ===
// Counter 结构体(模拟类)
typedef struct Counter Counter;
struct Counter {
// 数据成员(原闭包捕获的状态)
int x;
// 方法(函数指针)
char* (*toString)(Counter*);
void (*add)(Counter*);
void (*remove)(Counter*);
};
// Counter 方法的函数实现
char* Counter_toString(Counter* self) {
char* buffer = (char*)malloc(50 * sizeof(char));
snprintf(buffer, 50, "Counter x: %d", self->x);
return buffer; // 调用者负责释放
}
void Counter_add(Counter* self) {
self->x++;
}
void Counter_remove(Counter* self) {
// 由于数据直接嵌入结构体,无需特殊清理
free(self); // 释放整个结构体
}
// Counter 的"构造函数"
Counter* createCounter(int x) {
Counter* counter = (Counter*)malloc(sizeof(Counter));
counter->x = x; // 初始化数据
// 绑定方法
counter->toString = Counter_toString;
counter->add = Counter_add;
counter->remove = Counter_remove;
return counter;
}
// === 2. 抽象(Abstraction): Shape "基类" ===
// Shape 结构体(抽象接口)
typedef struct Shape {
// 方法(函数指针)
char* (*toString)(struct Shape*);
double (*area)(struct Shape*);
void (*draw)(struct Shape*);
void (*remove)(struct Shape*);
} Shape;
// === 3. 继承(Inheritance): ShapeBase 及其派生类 ===
// ShapeBase 结构体(基类)
typedef struct {
char* name;
double value;
} ShapeBase;
// ShapeBase 的初始化函数
void ShapeBase_init(ShapeBase* base, const char* name, double value) {
base->name = (char*)malloc(strlen(name) + 1);
strcpy(base->name, name);
base->value = value;
}
// ShapeBase 的清理函数
void ShapeBase_remove(ShapeBase* base) {
free(base->name);
}
// Circle 结构体(派生自 ShapeBase)
typedef struct {
Shape shape; // 必须是第一个成员,实现多态
ShapeBase base; // 嵌套基类(模拟继承)
// 派生类可添加额外成员
} Circle;
// Circle 的方法实现
char* Circle_toString(Shape* shape) {
Circle* self = (Circle*)shape; // 强制转换
char* buffer = (char*)malloc(100 * sizeof(char));
snprintf(buffer, 100, "Shape: %s (Circle)", self->base.name);
return buffer;
}
double Circle_area(Shape* shape) {
Circle* self = (Circle*)shape;
double r = self->base.value;
return 3.14159 * r * r;
}
void Circle_draw(Shape* shape) {
Circle* self = (Circle*)shape;
double a = shape->area(shape);
printf("Drawing Circle: %s, area: %f\n", self->base.name, a);
}
void Circle_remove(Shape* shape) {
Circle* self = (Circle*)shape;
ShapeBase_remove(&self->base);
free(self);
}
// Circle 的"构造函数"
Shape* createCircle(const char* name, double radius) {
Circle* circle = (Circle*)malloc(sizeof(Circle));
ShapeBase_init(&circle->base, name, radius);
// 创建Shape接口(多态)
Shape* shape = (Shape*)circle;
shape->toString = Circle_toString;
shape->area = Circle_area;
shape->draw = Circle_draw;
shape->remove = Circle_remove;
return shape;
}
// Square 结构体(派生自 ShapeBase)
typedef struct {
Shape shape; // 必须是第一个成员
ShapeBase base; // 嵌套基类
} Square;
// Square 的方法实现
char* Square_toString(Shape* shape) {
Square* self = (Square*)shape;
char* buffer = (char*)malloc(100 * sizeof(char));
snprintf(buffer, 100, "Shape: %s (Square)", self->base.name);
return buffer;
}
double Square_area(Shape* shape) {
Square* self = (Square*)shape;
double s = self->base.value;
return s * s;
}
void Square_draw(Shape* shape) {
Square* self = (Square*)shape;
double a = shape->area(shape);
printf("Drawing Square: %s, area: %f\n", self->base.name, a);
}
void Square_remove(Shape* shape) {
Square* self = (Square*)shape;
ShapeBase_remove(&self->base);
free(self);
}
// Square 的"构造函数"
Shape* createSquare(const char* name, double side) {
Square* square = (Square*)malloc(sizeof(Square));
ShapeBase_init(&square->base, name, side);
Shape* shape = (Shape*)square;
shape->toString = Square_toString;
shape->area = Square_area;
shape->draw = Square_draw;
shape->remove = Square_remove;
return shape;
}
// === 主函数(测试代码)===
int main() {
printf("=== 1. 封装示例 ===\n");
Counter* counter = createCounter(5);
char* str1 = counter->toString(counter);
printf("%s\n", str1);
free(str1);
counter->add(counter);
char* str2 = counter->toString(counter);
printf("%s\n", str2);
free(str2);
counter->remove(counter); // 释放Counter
printf("\n=== 2. 抽象、继承与多态示例 ===\n");
// 模拟多态容器(替代std::vector<Shape>)
Shape* shapes[2]; // 固定数组简化示例
shapes[0] = createCircle("MyCircle", 3.0);
shapes[1] = createSquare("MySquare", 2.5);
for (int i = 0; i < 2; i++) {
Shape* shape = shapes[i];
char* desc = shape->toString(shape);
double a = shape->area(shape);
printf("%s, Area: %f\n", desc, a);
shape->draw(shape);
printf("---\n");
free(desc); // 释放toString返回的字符串
}
// 释放资源
for (int i = 0; i < 2; i++) {
shapes[i]->remove(shapes[i]);
}
return 0;
}python
def extend(*father_class_list):
def decorator(sub_class):
def decorator_class(*args, **kwargs):
if len(father_class_list) == 0:
return sub_class(lambda: ...,*args, **kwargs)
else:
super_obj = lambda: ...
for father_class in father_class_list:
current_super_obj = father_class(super_obj, *args, **kwargs)
for k,v in current_super_obj.__dict__.items():
if not k.startswith('__'):
setattr(super_obj, k, v)
return sub_class(super_obj, *args, **kwargs)
return decorator_class
return decorator
@extend()
def Runner(self, *args, **kwargs):
self.speed = kwargs.get('speed', 10)
def run():
return f'{self.name} is running at {self.speed} km/h'
self.run = run
return self
@extend()
def Animal(self, *args,**kwargs):
self.name = kwargs.get('name', 'Unknown')
def to_string():
return f'{self.name} is an animal'
# bind the method to the object
self.to_string = to_string
return self
@extend(Animal,Runner)
def Dog(self, *args, **kwargs):
self.age = kwargs.get('age', 10)
self.super_to_string = self.to_string
def to_string():
print(self.super_to_string())
return f'{self.name} is {self.age} years old, running at {self.speed} km/h'
# bind the method to the object
self.to_string = to_string
return self
dog = Dog(name='Rex', age=5)
print(dog.to_string())
"""
运行结果:
Rex is an animal
Rex is 5 years old, running at 10 km/h
"""lua
-- 通过闭包实现类(而不是使用表)
-- 实现:封装、继承、多态、抽象
-- 1. 基类 Animal (抽象类)
local function Animal(name)
-- 【封装】:name 是局部变量,外部无法直接访问,只能通过闭包方法访问
-- self 是对外暴露的接口表
local self = {}
-- 【抽象】:定义接口,基类中可以抛出错误或提供默认实现
function self.speak()
error("Abstract method 'speak' must be implemented by subclass")
end
-- 公共方法
function self.getName()
return name
end
return self
end
-- 2. 子类 Dog
local function Dog(name, breed)
-- 【继承】:首先调用父类构造函数获取实例
local self = Animal(name)
-- 子类私有属性
local _breed = breed
-- 保存父类的方法(如果需要调用父类实现)
-- local super_speak = self.speak
-- 【多态】:重写父类方法
function self.speak()
return "Woof! I am " .. self.getName()
end
-- 子类特有方法
function self.getBreed()
return _breed
end
return self
end
-- 3. 子类 Cat
local function Cat(name)
-- 【继承】
local self = Animal(name)
-- 【多态】:重写父类方法
function self.speak()
return "Meow! I am " .. self.getName()
end
-- 子类特有方法
function self.purr()
return self.getName() .. " is purring..."
end
return self
end
-- --- 测试代码 ---
print("=== 1. 测试 Dog (继承与多态) ===")
local dog = Dog("Buddy", "Golden Retriever")
print("Name:", dog.getName()) -- 调用父类方法
print("Breed:", dog.getBreed()) -- 调用子类方法
print("Speak:", dog.speak()) -- 多态行为
print("\n=== 2. 测试 Cat (继承与多态) ===")
local cat = Cat("Whiskers")
print("Name:", cat.getName())
print("Speak:", cat.speak())
print("Action:", cat.purr())
print("\n=== 3. 测试封装性 ===")
print("dog.name is:", dog.name) -- nil,无法直接访问闭包内的局部变量
print("\n=== 4. 测试抽象性 ===")
local status, err = pcall(function()
local a = Animal("Unknown")
a.speak()
end)
if not status then
print("Expected error caught: " .. err)
end