抽象和适当的班级设计

时间:2014-01-22 19:06:15

标签: c# class oop constructor

我不是编程的新手,但对OOP来说相对较新,所以我有一个设计问题。实际上,我在同一个问题中遇到了两个问题。

为了简单起见,我们假设我正在设计一个FruitBasket类。除了FruitBasket类之外,我还将设计一个Apple类,一个Orange类和一个Pear类。每当我实例化FruitBasket类型的对象时,它将自动以has-a关系实例化这些其他类。

class Apple { //Apple implementation here }

class Orange { //Orange implementation here }

class Pear { //Pear implementation here }

class FruitBasket
{
     Apple _apple;
     Orange _orange;
     Pear _pear;

     public FruitBasket()
     {
          _apple = new Apple();
          _orange = new Orange();
          _pear = new Pear();
     }
}

class Program
{
     FruitBasket _fruitBasket;

     static void Main()
     {
          _fruitBasket = new FruitBasket();
     }
}

好的,这是我的问题:

  1. 如图所示,在FruitBasket构造函数中实例化各种水果对象是否可以接受,或者这是不好的做法?
  2. 如果每个水果篮要包含所有三种水果,这种方法似乎很好,但是,如果我希望实例化只有AppleOrange的水果篮怎么办? PearOrangeApplePear?等等。最好的方法是什么?
  3. 创建一个FruitBasket类是否会更好地声明可能进入篮子的每个水果并传递一些参数来告诉FruitBasket类实例化哪些水果类?

    我真的不知道哪种方法最有效,或者我的想法是否在球场。

6 个答案:

答案 0 :(得分:0)

我的建议是不为FruitBasket创建默认构造函数。这样您就可以使用Object Initializer语法来完成您所说的内容。您需要更改FruitBasket类,如下所示:

public class FruitBasket
{
    public Apple apple { get; set; }
    public Orange orange { get; set; }
    public Pear pear { get; set; }
}

然后您将能够按如下方式创建FruitBasket:

var fb1 = new FruitBasket { apple = new Apple() };
var fb2 = new FruitBasket { pear = new Pear() };
var fb3 = new FruitBasket { apple = new Apple() orange = new Orange() };

Object Initializer语法非常强大,如果你的类真的只是一个“属性包”,它通常是最简单的方法。

编辑:您可能还想让您的水果继承自Fruit基类。如果您这样做,则可以结合使用对象初始化语法和集合初始化语法。如果您将FruitBasket课程更改为以下内容:

public class FruitBasket
{
    public List<Fruit> fruit { get; set; }
}

您可以按如下方式初始化FruitBasket

var fb3 = new FruitBasket{ fruit = new List<Fruit> { new Apple(), new Orange() } };
var fb4 = new FruitBasket{ fruit = new List<Fruit> { new Orange() } };
var fb5 = new FruitBasket{ fruit = new List<Fruit> { new Apple(), new Orange(), new Pear() } };

答案 1 :(得分:0)

果篮必须有水果,有时可能是空的?你可以重复任何水果吗?如果是,你应该研究继承和泛型,你必须有一个基类Fruit,而篮子可能只是一个通用的列表

abstract class Fruit
{

}
class Apple : Fruit
{
    //Apple implementation here
}

class Orange : Fruit
{
    //Orange implementation here
}

class Pear : Fruit
{
    //Pear implementation here
}

class Program
{

    static void Main()
    {
        List<Fruit> _fruitBasket = new List<Fruit>();

        _fruitBasket.Add(new Orange());
        _fruitBasket.Add(new Apple());
    }
}

答案 2 :(得分:0)

或者你可以做以下事情,让你的篮子尽可能丰富:

abstract class Fruit {}
class Apple :Fruit  { //Apple implementation here }

class Orange : Fruit  { //Orange implementation here }

class Pear :Fruit  { //Pear implementation here }

class FruitBasket
{
     public List<Fruit> Contents {get;set;}

     public FruitBasket()
     {
       Contents = new List<Fruit>{new Apple(), new Orange(), new Pear()};
     }
}

答案 3 :(得分:0)

以下是我如何处理这个问题。而不是在篮子中有一组预定义的水果,通过使用水果收集使其变得灵活。您将无法将它们传递给构造函数,而是通过方法添加它们。为此,每个水果类都继承了相同的界面(例如IFruit)

所以你有

class Apple : IFruit { ... }
class Orange : IFruit { ... }
etc

好处是你可以添加任意多种类型的水果,不仅限于苹果,橙子和梨。

Fruitbasket可能看起来像这样

public class FruitBasket {
    public FruitBasket() {
        _basket = new List<IFruit>();
    }

    public List<IFruit> Fruits {
        get { return _basket; }
    } 

    public AddFruit(IFruit fruit) {
        _basket.Add(fruit);
    }

    private readonly List<IFruit> _basket 
}

答案 4 :(得分:0)

我会以不同的方式设计它。

class Fruit
{
}

class Apple : Fruit
{ //Apple implementation here }

class Orange : Fruit
{ //Orange implementation here }

class Pear : Fruit
{ //Pear implementation here }

class FruitBasket
{
     Ilist<Fruit> Fruits;

     public FruitBasket()
     {
          Fruits =new List<Fruit>();
     }

     public AddFruit(Fruit)
     {
     // Add Fruit implementation here
     }

      public RemoveFruit(Fruit)
     {
     // Remove Fruit implementation here
     }

}

class Program
{
     FruitBasket _fruitBasket;

     static void Main()
     {
         Fruit orange=new Orange(); 
         _fruitBasket = new FruitBasket();
         _fruitBasket.AddFruit(orange);
     }
}

答案 5 :(得分:0)

据推测,FruitBasket可以容纳任何类型的水果吗?这听起来像多态性和依赖性倒置的情况。

class FruitBasket {
  readonly List<Fruit> _fruits = new List<Fruit>();
  public FruitBasket(params Fruit[] fruits) {
    _fruits.AddRange(fruits);
  }
}
interface Fruit {}
class Apple : Fruit {}
class Orange : Fruit {}

在OOP中,你通常会传递依赖关系。'预先知道'依赖关系是什么更具程序性。