Is-A vs Has-A关系

时间:2013-10-29 19:04:22

标签: c#

新手问题,我的课程讲师已经有效地混淆了我的焦油。 Is-A关系就是说Dog是动物。然后你将Animal作为基类,将Dog作为衍生类。

但是对于我们的Class Project,我必须基于一个接口创建一个类。使用一个单独的类,只有一种方法可以给出一个随机数。看起来它们并没有真正相关,但我必须从主类中调用randomNumber方法。

他在指示中的问题(这很糟糕)说要弄清楚这是一个IS-A还是HAS-A关系。根据事实,我会说这是一个HAS-A关系,但我不知道如何引用该类,但是为了将一个变量分配给该类,我可以使用它。

有没有其他方法来引用我不认识的课程?

Devices randomMeasure = new Devices();  //Random measurement Class
this.mostRecentMeasure = randomMeasure.GetMeasurement();

6 个答案:

答案 0 :(得分:6)

接口是一种Can-Do关系。
您可以将类的实例分配给任何类型为

的变量
  1. 班级本身或
  2. 该类的基类之一或
  3. 该类或其基类之一实现的接口。
  4. 在您的示例中(案例3),这意味着:

    IDevice randomMeasure = new Devices();
    randomMeasure.GetMeasurement();
    

    这个概念被称为polymorphism

答案 1 :(得分:5)

如果您的班级继承自其他班级,则为“IS-A”关系。

如果将类传递给构造函数中的另一个类,则这是“HAS-A”关系。

e.g。

public class foo : bar
{
    // IS-A
}



public interface IBar
{
}

public class Bar : IBar
{
}

public class Foo : IBar
{
    private Bar _bar;

    public foo(Bar bar)
    {
        _bar = bar;

    }

    // HAS-A
}

但是,你要问的是什么并不明显。在第二种情况下,Foo IS-A IBar HAS-A Bar

答案 2 :(得分:3)

这是一个IS-A关系,

要引用它,您应该创建具体类的实例并将其分配给接口类型的变量:

interface IMeasureable 
{
    public int GetMeasurement();
}
class Device : IMeasureable 
{
    public int GetMeasurement() 
    {
        return .... 
    }
}
class App 
{
    public void Main() 
    {
         IMeasureable thing = new Device();
         int x = thing.GetMeasurement();
    }
}

答案 3 :(得分:2)

回答你的问题(虽然我不知道你为什么这么问) 你可以

  1. 实例化课程

  2. 让它静止

  3. 将类对象保存在应用程序变量/缓存/视图状态等

  4. 使用扩展方法,它将为您提供随机数(在这种情况下您不必使用其他类)

答案 4 :(得分:2)

如果我们接受接口是CAN-DO关系,那么教授必须询问两个具体类之间的关系。我会将这些课程称为ClassBasedOnInterfaceSeperateClass。其中ClassBasedOnInterface又名“主要阶级”。我们也知道要求是:

  

我必须从主类中调用randomNumber方法。

interface IMyInterface
{
    void Call();
}

//Requirement: I have to call the randomNumber Method from the main class.
public class ClassBasedOnInterface : IMyInterface
{
    SeperateClass hasASeperateClass = new SeperateClass();

    public void Call()
    {
        //Could be local variable.  
        //Or, the professor could be implying that ClassBasedOnInterface has a SeperateClass 
        //member that is used to make the call to GetRandomNumber().  
        //Or, GetRandomNumber() could be static.
        //var seperateClass = new SeperateClass();//I do not consider a private local variable a HAS-A relationship
        //seperateClass.GetRandomNumber();

        hasASeperateClass.GetRandomNumber();
    }
}

public class SeperateClass
{
    public void GetRandomNumber()
    {

    }
}

仍有许多悬而未决的问题。但是,没有理由相信ClassBasedOnInterface也来自SeperateClass。有证据表明SeperateClassClassBasedOnInterface的成员,因为要求是ClassBasedOnInterface必须调用SeperateClass.GetRandomNumber()。换句话说,没有理由相信存在IS-A关系。

出于这个原因,我相信答案是:

ClassBasedOnInterfaceSeperateClass具有HAS-A关系

答案 5 :(得分:1)

接口描述了有关类的内容,但不一定定义它。正如其他人所说,这更像是一种可以做的关系。你能和这门课一起做点什么吗?

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