Vb.net 如何在实现相同接口的两种类型之间进行强制转换

Vb.net 如何在实现相同接口的两种类型之间进行强制转换,vb.net,design-patterns,contravariance,Vb.net,Design Patterns,Contravariance,我有一个重叠的数据对象,需要给至少一个,可能更多的,几种计算方法,以产生一个共同的数据对象 我认为最好的解决方法是实施两种共价反变异,但我还不能完全理解这会是什么样子,所以我愿意接受其他建议。实际上,Animal/IAnimal和Noise有很多数据属性,所以我希望尽量避免在构造函数中映射它们 Public Class Noise Public Property Sound() As String Public Sub Listen() Console.Write

我有一个重叠的数据对象,需要给至少一个,可能更多的,几种计算方法,以产生一个共同的数据对象

我认为最好的解决方法是实施两种共价反变异,但我还不能完全理解这会是什么样子,所以我愿意接受其他建议。实际上,Animal/IAnimal和Noise有很多数据属性,所以我希望尽量避免在构造函数中映射它们

Public Class Noise
    Public Property Sound() As String
    Public Sub Listen()
        Console.WriteLine(sound)
    End Sub 
End Class

Public Interface IAnimal
    Function Speak() As Noise()
    Property Name() As String
End Interface

Public Class Dog
    Implements IAnimal
    Public Function Speak() As Noise() Implements IAnimal.Speak
        return { new Noise() with { .Sound = "Bark" } }
    End Function
    Public Property Name As String Implements IAnimal.Name
End Class

Public Class Cat
    Implements IAnimal
    Public Function Speak() As Noise() Implements IAnimal.Speak
        return { new Noise() with { .Sound = "Meow" } }
    End Function
    Public Property Name As String Implements IAnimal.Name
End Class
下面的测试生成正确的输出,如果IAnimal是具有抽象函数speak的抽象基类,那么它也可以工作。如果我理解正确,这意味着协变行为已经实现,因为这是您对继承的期望

 Public Sub ListenToAnimalsTest()
    dim spot = new Dog() With {.Name = "Spot" }
    dim kitty = new Cat() With {.Name = "Kitty" }

    Dim animalList As List(of IAnimal)
    animalList.Add(spot)
    animalList.Add(kitty)
    For Each animal in animalList 
        Console.WriteLine(animal.Name)
        animal.Speak().Listen()
    Next
End Sub
问题是我还需要一只宠物猫

Public Class CatDog
    Implements IAnimal

    Public Overrides Function Speak() As Noise() Implements IAnimal.Speak
        dim myself As Cat = me
        dim andI As Dog = me
        Return { myself.Speak(), andI.Speak()}
    End Function

   Public Property Name As String Implements IAnimal.Name
End Class
我想知道我是否可以使用逆变来允许猫或狗使用动物或动物,很明显,这只是填充了普通属性

有什么想法或建议吗


关于Decorator/Visitor模式,我希望能够通过父级或接口的另一个实现来继续实现任何最终实现的模式,以便让动物说话不会改变。这意味着Decorator的catDog实现仍然需要将IAnimal视为一只猫,然后是一只狗,否则我将在两个地方复制如何吠叫和喵喵叫,不是吗?

协方差和逆变是泛型类型的属性(例如,
列表(IAnimal)
),这与您的问题并不相关


VB.NET不允许真正的多重继承,但您可以创建接口
ICat
IDog
,每个接口都实现
IAnimal
。然后,您可以使用显式接口实现让您的
IAnimal
吠叫或喵喵叫,这取决于您的对象被转换为哪个接口。

协方差和逆变是泛型类型的属性(例如
列表(IAnimal)
),这与您的问题并不相关


VB.NET不允许真正的多重继承,但您可以创建接口
ICat
IDog
,每个接口都实现
IAnimal
。然后,您可以使用显式接口实现让您的
IAnimal
吠叫或喵喵叫,这取决于您的对象被转换为哪个接口。

您已经拥有了它,因此IAnimal可以是猫或狗。否则,您将无法将它们添加到IAnimal列表中。你真正的问题应该是:“我是否在尝试完成一些与多态性无关的事情?”。您可以使用一个接口在一个具体的类上设置规则,比如:“您必须做这些事情”。如果您正在尝试实现一个catdog。这与两个可以解释为或的类无关。当你使用一个界面来实现不同对象的相似方法时,不是两次相同的事情。你是对的,把猫变成狗不是我真正想要的。catDog的全部要点是通过简单地调用catDog.speak,在遍历列表的同时调用cat.speak,然后在同一组数据上调用dog.speak。您可以使用或模式。首先是在不继承的情况下向对象添加职责,这意味着在不更改对象本身的情况下实现未来的功能。你不用各种各样的CatDog、BirdDog或CatDogBat类,而是用各种各样的“装饰器”(噪音)来“装饰”一个“组件”(IAnimal)。你已经有了它,这样IAnimal就可以是猫或狗了。否则,您将无法将它们添加到IAnimal列表中。你真正的问题应该是:“我是否在尝试完成一些与多态性无关的事情?”。您可以使用一个接口在一个具体的类上设置规则,比如:“您必须做这些事情”。如果您正在尝试实现一个catdog。这与两个可以解释为或的类无关。当你使用一个界面来实现不同对象的相似方法时,不是两次相同的事情。你是对的,把猫变成狗不是我真正想要的。catDog的全部要点是通过简单地调用catDog.speak,在遍历列表的同时调用cat.speak,然后在同一组数据上调用dog.speak。您可以使用或模式。首先是在不继承的情况下向对象添加职责,这意味着在不更改对象本身的情况下实现未来的功能。你不用各种各样的CatDog、BirdDog或CatDogBat类,而是用各种各样的“装饰器”(噪音)来“装饰”一个“组件”(IAnimal)。。。叹息。。。在c#中,我可以继承这两个角色,以便对其中一个角色进行转换。无论我如何施放AnimalCatDog,Name总是指向同一个对象吗?C#也没有多重继承,是的,您可以在
IAnimal
上实现
Name
,因此无论您如何施放它,它总是返回相同的对象。VB再次罢工。。。叹息。。。在c#中,我可以继承这两个角色,以便对其中一个角色进行转换。无论我如何施放AnimalCatDog,Name是否总是指向同一个对象?C#也没有多重继承,是的,您可以在
IAnimal
上实现
Name
,因此无论您如何施放,它总是返回相同的对象。