我不是编程的新手,但对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();
}
}
好的,这是我的问题:
FruitBasket
构造函数中实例化各种水果对象是否可以接受,或者这是不好的做法?Apple
和Orange
的水果篮怎么办? Pear
和Orange
? Apple
和Pear
?等等。最好的方法是什么?创建一个FruitBasket
类是否会更好地声明可能进入篮子的每个水果并传递一些参数来告诉FruitBasket
类实例化哪些水果类?
我真的不知道哪种方法最有效,或者我的想法是否在球场。
答案 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中,你通常会传递依赖关系。'预先知道'依赖关系是什么更具程序性。