2013-09-27 21 views
4

我有几个班在我的系统这是使用多态性

//this was not made an Interface for some WCF reasons 
public abstract class BaseTransmission 
{ 
    protected internal abstract string Transmit(); 

    //other common properties go here 
} 

和几个子类像

public class EmailTransmission : BaseTransmission 
    { 
     //This property is added separately by each child class 
     public EmailMetadata Metadata { get; set; } 

     protected internal override string Transmit() 
     { 
      //verify email address or throw 
      if (!Metadata.VerifyMetadata()) 
      { 
       throw new Exception(); 
      } 
     } 
    } 

在其他地方以正确的方式,我创建了一个方法与签名Transmit(BaseTransmission transmission) 。我从我的代码的另一部分调用这种方法是这样的:

TransService svc = new TransService(); 
EmailTransmission emailTrans = new EmailTransmission(); // this inherits from BaseTransmission 
svc.Transmit(emailTrans); 

这解决了我的目的。但通常当我看到多态性的例子时,我总是看到引用类型是基类类型,并且它指向了子类类型的一个实例。所以在多态性

的典型例子,通常
EmailTransmission emailTrans = new EmailTransmission(); 

通常会

BaseTransmission emailTrans = new EmailTransmission(); 

我不能这样做,因为EmailTransmission EmailMetadata不同于可以说FaxMetadata。因此,如果我将引用声明为BaseTranmission类型并将其指向EmailTranmission类型的实例,则我将无法访问EmailTransmission的EmailMetadata属性。

我想知道我在上面做的是多态的滥用以及是否以某种方式“破坏”了多态。如果它滥用多态性,那么做到这一点的正确方法是什么。

+1

是的,这对我来说很好。该服务本身与基类一起工作,所以你应该没问题。 – Jeff

+2

您使用'BaseTransmission'类型的变量的原因是因为代码不关心实际类型是什么。这很典型,因为它只会调用'BaseTransmission'类型的方法。但是,由于您正在调用某个子类中的特定于类型的方法,因此您必须使用该类型的变量。这段代码没有错。 –

+2

得到我的一件事就是你的评论“这个属性是由每个孩子班级单独添加的”。所以这听起来像BaseTransmission的所有孩子将有一个元数据属性。我想知道在理想情况下,您是否有Metadata的接口或基类,并在BaseTransmission中公开访问器。尽管如此,它是完美无瑕的,绝对没有什么是坏的。 –

回答

1

这是完全有效的。多态模式用于TransService服务Transmit方法。 它可以在一个或多个类中使用可以为morphed的类。

您使用基类或派生类声明变量的事实取决于您,并取决于您的具体情况。

0

这应该是完全没问题的。在传输方法中,该对象被称为BaseTransmission,因此“向下转换”不太明显。 (曾以此为事前的评论,但是这确实应该是一个答案)

0

那么,这是perfetly有效的情况下:当您使用基类像 TransService.Trasmit方法的基础参数。

看起来奇怪的唯一事情是:

protected internal abstract string Transmit(); 

真的需要protectedinternal? 如果是,请跳过这个概念。

0

一般来说,你会更喜欢使用基本类型

BaseTransmission emailTrans = new EmailTransmission(); 

这样可以使你的抽象干净,可以帮助您不要重复自己。这在以下场景中很有用:假设用户可以选择如何与他/她联系(电子邮件,传真,文本)。当你需要发送一些东西时,你只需要一个单个方法,该方法需要BaseTransmission对象和参数,比如BaseParameter

注:如果它看起来,好像没有太多的代码可以共享,你可以定义一个接口ITransmitter并用它来显示一个类可以送东西,如:

ITransmitter transmitter = new EmailTransmission(); 
0

什么你在做的事情是绝对正确的,应该没有问题地工作。将子类传递给接受基类的函数/方法应该不成问题。

但是,对于你的例子这里:

这解决了我的目的。但通常当我看到多态性的例子时,我总是看到引用类型是基类类型,并且它指向了子类类型的一个实例。因此,在多态的典型例子,通常

EmailTransmission emailTrans = new EmailTransmission(); 

通常会

BaseTransmission emailTrans = new EmailTransmission(); 

这样做,如果BaseTransmission是一个接口或抽象类,那么你就需要构建一个特定版本BaseTransmission。有时候如果你不需要额外的组件,有些人喜欢用它来保持代码的清洁。这方面最常见的用法是看到泛型当您想要创建例如List,而是需要实现一个特定版本的操作系统,如ListArrayListLinkedList