接口描述了一个类的一些东西,但不一定定义它。正如其他人所说,这更像是一种可以做的关系。你能对这个班级做点什么吗?等等。
Has-A 关系将是一个利用其他类来表示 0..* 关系中的东西的类。
// This interface doesn't really define what a class is, only
// that it can, in fact, have Cheeseburgers.
public interface ICanHasCheeseburgers
{
List<Cheeseburger> Cheeseburgers { get; }
}
// This abstract class, defines what a derived class 'is'.
// If you are familiar with biology, imagine: kingdom, phylum, class, order,
// genius, species. It's different levels of abstraction for a 'thing'.
public abstract class Animal
{
}
// The cat class derives from the Animal class just as a Dog class might.
// This is a Is-A relationship; the Cat is an Animal. It also implements
// the ICanHasCheeseburgers interface which represents a Can-Do relationship.
public class Cat : Animal, ICanHasCheeseburgers
{
// this property represents a Has-A relationship between our Cat
// class and a Cheeseburger class. The cat can have any number of
// Cheeseburger objects.
public List<Cheeseburger> Cheeseburgers { get; private set; }
public Cat(RandomNumberGenerator generator)
{
if (generator != null)
{
var number = generator.GetRandom();
var burgers = new List<Cheeseburger>();
while(number > 0) {
burgers.add(new Cheeseburger());
number--;
}
Cheeseburgers = burgers;
}
}
}
Can-Do 和 Is-A 关系允许我们抽象逻辑。假设我们有任意数量,我们想知道它们总共有Animals
多少。Cheeseburgers
如果我们必须为每种动物编写一个方法,然后尝试将它们加在一起,这将不会很有趣。但是通过抽象,我们可以编写一种方法。
public static class Util
{
public int GetTotalCheeseburgerCount(List<Animal> animals)
{
var total = 0;
foreach(var animal in animals)
{
// not every animal can have cheeseburgers, so we
// can ignore this animal if it can't.
var canHasCheeseburger = animal as ICanHasCheeseburger;
if (canHasCheeseburger != null)
{
if (canHasCheeseburger.Cheeseburgers != null)
{
total += canHasCheeseburger.Cheeseburgers.Count;
}
}
}
return total;
}
}