简体   繁体   中英

Is this a correct way to use polymorphism

I have a couple of classes in my system

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

    //other common properties go here
}

And a few child classes like

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();
            }
        }
    }

Elsewhere, I have created a method with signature Transmit(BaseTransmission transmission) . I am calling this method from another part of my code like this:

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

This solves my purpose. But usually when I see examples of polymorphism, I always see that the reference type is base class type and it points to an instance of child class type. So usually in typical examples of polymorphism

EmailTransmission emailTrans = new EmailTransmission();

will usually be

BaseTransmission emailTrans = new EmailTransmission();

I cannot do this because EmailTransmission EmailMetadata is different from lets say FaxMetadata. So if I declare the reference to be of BaseTranmission type and point it to an instance of EmailTranmission type, I lose access to the EmailMetadata property of the EmailTransmission.

I want to know whether what I am doing above is a misuse of polymorphism and whether it 'breaks' polymorphism in some way. And if it is abusing polymorphism, whats the right way to do this.

This is perfectly valid. The polymorphic pattern is used in the TransService service Transmit method. It works with a class that can be morphed in one or more classes.

The fact that you declare the variable using the base class or the derived class is up to you and depends on your specific case.

That should be completely fine. Within the transmit method the object is referenced as BaseTransmission, the "downcasting" is therefore less obvious. (had this as comment beforehand, but this should really be an answer)

Well, this is perfetly valid case: as you use base class type like a base parameter in the TransService.Trasmit method.

The only thing which looks strange is:

protected internal abstract string Transmit();

do you really need protected and internal ? If yes, just skip this notion.

Generally you would prefer using base type

BaseTransmission emailTrans = new EmailTransmission();

This keeps you abstraction clean and helps you with Don't Repeat Yourself. This will be useful in the following scenario: suppose a user can select how she/he can be contacted (email, fax, text). When you need to send something you just have a single method that takes BaseTransmission object and parameters, say BaseParameter .

Note: if it looks, as if there is not much code can be shared, you can define an interface ITransmitter and use it to show that a class can send something, like:

ITransmitter transmitter = new EmailTransmission();

What you are doing is absolutely correct and should work without issue. Passing a child class to a function/method that takes the base class should not be an issue.

However, regarding your example here:

This solves my purpose. But usually when I see examples of polymorphism, I always see that the reference type is base class type and it points to an instance of child class type. So usually in typical examples of polymorphism

EmailTransmission emailTrans = new EmailTransmission();

will usually be

BaseTransmission emailTrans = new EmailTransmission();

This is done if BaseTransmission is an interface or abstract class and you then need to construct a specific version of BaseTransmission . Sometimes if you don't need the extra components some people like to use this to keep their code clean as well. The most common usage of this is seen with generics such as when you want to create a List for example, but need to implement a specific version os List such as ArrayList or LinkedList

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM