use crate::size::Size;
pub struct Car {
pub name: String,
pub color: (u32, u32, u32),
pub size: Size,
pub model: u32,
pub private: i32,
}
impl Car {
pub fn new() -> Self {
Car {
name: String::from("Default Template"),
color: (1, 0, 1),
size: Size::NORMAL,
model: 2019,
private: 2,
}
}
}
pub trait CommontMethods {
fn change_name_and_model(&mut self, private: i32);
}
pub trait PrintChanges {
fn print_changes(&self);
}
impl CommontMethods for Car {
fn change_name_and_model(&mut self, private: i32) {
println!("{}", self.name);
self.model = 2000;
self.private = private;
self.print_changes();
}
}
impl PrintChanges for Car {
fn print_changes(&self) {
println!("Model :{} , private : {}", self.model, self.private);
}
}
Run Code Online (Sandbox Code Playgroud)
这是Car它具有_name_and_model()调用的函数的结构print_changes()。Honda具有字段的结构体car : Car {...}
调用时honda.change_name_and_model(),我希望它实际调用print_changes()本田而不是汽车中实现的函数。
use crate::car::*;
use crate::size::Size;
pub struct Honda {
pub car: Car,
lights_on: bool,
}
impl Honda {
pub fn new() -> Self {
Honda {
car: Car {
name: String::from("Honda"),
color: (1, 1, 1),
size: Size::BIG,
model: 2002,
private: 3,
},
lights_on: true,
}
}
}
impl PrintChanges for Honda {
fn print_changes(&self) {
self.car.print_changes();
println!("this is usefull !");
}
}
Run Code Online (Sandbox Code Playgroud)
所以当我想这样使用它时:
fn main() {
let mut honda = Honda::new();
honda.car.change_name_and_model(0);
}
Run Code Online (Sandbox Code Playgroud)
该change_name_and_model()函数调用 的汽车实现print_changes(),但我希望它改为调用 Honda one。
这可能吗?
请原谅我在这里对 OO 进行了一些重新设计。我将创建Car我的基础“类” - 或特征,Honda并Chevrolet从中继承。
如果您来自 Java,请将特征视为接口或抽象类。由于特征可以包含方法的默认实现,因此它们更像抽象类 - 只不过它们不能具有数据成员。
假设它Car继承了另一个特征,PrintsUpdate。这意味着Honda也Chevrolet必须实现它(或者如果PrintsUpdate有默认实现,则覆盖它是可选的)。
如果我们一切都做对了,我们就能得到我们想要的多态行为。例如,我们可以编写带有指向Car特征的指针并调用其方法的函数,并观察调用了正确的重写实现。
pub fn polymorphism_test()
{
let mut honda = Honda::new("Civic", "Foolton", "Blue");
let mut chevy = Chevrolet::new("Corvette", "Barbie", "Red");
update_car(&mut honda, "Bazner", "Green");
update_car(&mut chevy, "Quxner", "Orange");
}
pub fn update_car(car: &mut dyn Car, owner: &str, color: &str) {
println!("Updating a {}...", car.make());
car.update(owner, color);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Updating a Honda...
Printing changes for Bazner's Green Honda Civic
Updating a Chevrolet...
Printing changes for Quxner's Orange Chevrolet Corvette
Run Code Online (Sandbox Code Playgroud)
这是我们的基本特征。我Car继承自PrintsUpdate:
Updating a Honda...
Printing changes for Bazner's Green Honda Civic
Updating a Chevrolet...
Printing changes for Quxner's Orange Chevrolet Corvette
Run Code Online (Sandbox Code Playgroud)
请注意,Car::update()正在调用尚未实现的方法。这可以。Chevrolet如果他们继承,则Honda必须实施它们Car。
这是我们的Honda“班级”:
pub trait Car: PrintsUpdate {
fn make(&self) -> &str;
fn set_owner(&mut self, name: &str);
fn set_color(&mut self, name: &str);
fn update(&mut self, owner: &str, color: &str)
{
self.set_owner(owner);
self.set_color(color);
self.print_changes();
}
//fn print_changes(&self);
}
pub trait PrintsUpdate {
fn print_changes(&self) {
println!("Default implementation for PrintsUpdate...");
}
}
Run Code Online (Sandbox Code Playgroud)
和Chevrolet:
pub struct Honda {
make: String,
model: String,
owner: String,
color: String,
}
impl Honda {
pub fn new(model: &str, owner: &str, color: &str) -> Self {
Honda {
make : "Honda".into(), model: model.into(),
owner: owner.into(), color: color.into()
}
}
}
impl Car for Honda {
fn make(&self) -> &str {
&self.make
}
fn set_owner(&mut self, name: &str) {
self.owner = name.into();
}
fn set_color(&mut self, color: &str) {
self.color = color.into();
}
}
impl PrintsUpdate for Honda {
fn print_changes(&self) {
println!("Printing changes for {}'s {} Honda {}",
self.owner, self.color, self.model);
}
}
Run Code Online (Sandbox Code Playgroud)
如果Chevrolet选择不覆盖PrintsUpdate::print_changes()也没关系,因为它有一个默认实现。Chevrolet::prints_changes()如果没有注释掉的话,顶部的输出就是它的样子。下面是注释掉的。
再次运行该polymorphism_test()函数,我们得到:
Updating a Honda...
Printing changes for Bazner's Green Honda Civic
Updating a Chevrolet...
Default implementation for PrintsUpdate...
Run Code Online (Sandbox Code Playgroud)