没有类只有接口的语言(rust)如何实现继承又避免代码重复?
rust没有类只有接口, 不过接口可以继承也可以为method定义默认实现, 可是接口只能声明method不能声明成员属性, 于是default method里也不能直接访问成员属性
如果某些default method一定要访问成员属性才能实现的话, 除了在接口里写一大堆的getter/setter外有什么方法能解决这个问题呢?
现在用getter/setter写出来是这样下面↓这样, 然后每次impl都要复制一大段的getXXX/setXXX...
pub trait Sprite2D<T>: Sprite<T> {
fn get_position(&self) -> Vector2D;
fn set_position(&mut self, p: Vector2D);
fn get_direction(&self) -> f64;
fn set_direction(&mut self, d: f64);
fn get_scale_x(&self) -> f64;
fn set_scale_x(&mut self, sx: f64);
fn get_scale_y(&self) -> f64;
fn set_scale_y(&mut self, sy: f64);
fn get_matrix(&self) -> Matrix2D {
let position = self.get_position();
let mat_s = Matrix2D::create_scale(self.get_scale_x(), self.get_scale_y());
let mat_r = Matrix2D::create_rotate(self.get_direction());
let mat_p = Matrix2D::create_translate(position.x(), position.y());
mat_s.append(&mat_r).append(&mat_p)
}
fn get_inv_matrix(&self) -> Matrix2D {
self.get_matrix().inv()
}
fn translate(&mut self, dx: f64, dy: f64) {
let pos = self.get_position() + Vector2D::new(dx, dy);
self.set_position(pos);
}
fn rotate(&mut self, rad: f64) {
let dir = self.get_direction() + rad;
self.set_direction(dir);
}
fn scale(&mut self, sx: f64, sy: f64) {
let n_sx = self.get_scale_x() * sx;
let n_sy = self.get_scale_y() * sy;
self.set_scale_x(n_sx);
self.set_scale_y(n_sy);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我个人的建议,可以有以下办法。
方案一,手动添加继承类型和基类型之间的转换关系:
设计一个基类型
BaseSprite
, 它有一系列的成员函数。所有的子类都必须有一个基类型的成员变量,并且实现
AsRef<BaseSprite>
。这么设计的缺点是每次调用基类型的函数,需要先使用
as_ref()
。至于每个子类型都需要实现trait
,其实可以用一个宏来完成。方案二,利用
Deref
这个特殊的trait
,实现基类型和子类型之间的转换:设计一个基类型
BaseSprite
, 它有一系列的成员函数。所有的子类都必须有一个基类型的成员变量,并且实现
Deref<Target=BaseSprite>
。这样一来,所有子类型调用成员函数时,会自动去寻找基类型的成员函数。智能指针就是通过这种方式直接透明调用内部成员的方法的。
方案一和方案二对比,各有优缺点。方案一写起来比较麻烦,但是可以实现多继承;方案二相对简洁,但是不能实现多继承,一个类型只能实现一个
Deref
。Tarit Object啊
getter,setter 不需要啊,直接pub就行了啊。