A high covariance shows a strong relationship between the two variables, whereas a low covariance shows a weak relationship.
The covariance equation is used to determine the direction of the relationship between two variables–in other words, whether they tend to move in the same or opposite directions. This relationship is determined by the sign (positive or negative) of the covariance value.
Significance of the formula: Therefore the numerical value of covariance does not have any significance however if it is positive then both variables vary in the same direction else if it is negative then they vary in the opposite direction.
Covariance in Excel: Overview Covariance gives you a positive number if the variables are positively related. You'll get a negative number if they are negatively related. A high covariance basically indicates there is a strong relationship between the variables. A low value means there is a weak relationship.
The canonical example is a .clone()
/.copy()
method. So you can always do
obj = obj->copy();
regardless what obj's type is.
Edit: This clone method would be defined in the Object base class (as it actually is in Java). So if clone wasn't covariant, you would either have to cast, or would be restricted to methods of the root base class (which would have only very few methods, compared the class of the source object of the copy).
In general, covariance allows you to express more information in the derived class interface than is true in the base class interface. The behaviour of a derived class is more specific than that of a base class, and covariance expresses (one aspect of) the difference.
It's useful when you have related hierarchies of gubbins, in situations where some clients will want to use a base class interface, but other clients will use the derived class interface. With const-correctness omitted:
class URI { /* stuff */ };
class HttpAddress : public URI {
bool hasQueryParam(string);
string &getQueryParam(string);
};
class Resource {
virtual URI &getIdentifier();
};
class WebPage : public Resource {
virtual HttpAddress &getIdentifier();
};
Clients which know they have a WebPage (browsers, perhaps) know that it's meaningful to look at query params. Clients which are using the Resource base class know no such thing. They will always bind the returned HttpAddress&
to a URI&
variable or temporary.
If they suspect, but don't know, that their Resource object has an HttpAddress, then they can dynamic_cast
. But covariance is superior to "just knowing" and doing the cast for the same reason that static typing is useful at all.
There are alternatives - stick the getQueryParam
function on URI
but make hasQueryParam
return false for everything (clutters the URI interface). Leave WebPage::getIdentifier
defined to return URL&
, actually returning an HttpIdentifier&
, and have callers do a pointless dynamic_cast
(clutters the calling code, and the documentation of WebPage where you say "the URL returned is guaranteed to be dynamically castable to HttpAddress"). Add a getHttpIdentifier
function to WebPage
(clutters the WebPage
interface). Or just use covariance for what it's meant to do, which is express the fact that a WebPage
doesn't have an FtpAddress
or a MailtoAddress
, it has an HttpAddress
.
Finally there is of course a reasonable argument that you shouldn't have hierarchies of gubbins, let alone related hierarchies of gubbins. But those classes could just as easily be interfaces with pure virtual methods, so I don't think it affects the validity of using covariance.
I think covariance can be useful when declaring factory methods that return a specific class and not its base class. This article explains this scenario quite well, and includes the following code example:
class product
{
...
};
class factory
{
public:
virtual product *create() const = 0;
...
};
class concrete_product : public product
{
...
};
class concrete_factory : public factory
{
public:
virtual concrete_product *create() const
{
return new concrete_product;
}
...
};
I often find myself using covariance when working with existing code to get rid of static_casts. Usually the situation is similar to this:
class IPart {};
class IThing {
public:
virtual IPart* part() = 0;
};
class AFooPart : public IPart {
public:
void doThis();
};
class AFooThing : public IThing {
virtual AFooPart* part() {...}
};
class ABarPart : public IPart {
public:
void doThat();
};
class ABarThing : public IThing {
virtual ABarPart* part() {...}
};
This allows me to
AFooThing* pFooThing = ...;
pFooThing->Part()->doThis();
and
ABarThing pBarThing = ...;
pBarThing->Part()->doThat();
instead of
static_cast< AFooPart >(pFooThing->Part())->doThis();
and
static_cast< ABarPart >(pBarThing->Part())->doThat();
Now when coming across such code one could argue about the original design and whether there is a better one – but in my experience there are often constraints such as priorities, cost/benefit etc. which interfere with extensive design beautification and permit only small steps such as this one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With