Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么时候应该使用新类而不是添加新字段(作为状态)?_Java_C#_Oop_Design Patterns - Fatal编程技术网

Java 什么时候应该使用新类而不是添加新字段(作为状态)?

Java 什么时候应该使用新类而不是添加新字段(作为状态)?,java,c#,oop,design-patterns,Java,C#,Oop,Design Patterns,我看了一些设计模式书,注意到了一些有趣的地方:它们创建了很多类。有时,我似乎可以添加一个字段,而不是创建类。比如说 使用类的实现: public class Animal { } public class Dog : Animal { } 使用状态的实现: public class Animal { public AnimalType AnimalType; } var dog = new Animal(); dog.AnimalType = AnimalType.Dog;

我看了一些设计模式书,注意到了一些有趣的地方:它们创建了很多类。有时,我似乎可以添加一个字段,而不是创建类。比如说

使用类的实现:

public class Animal
{

}


public class Dog : Animal
{

}
使用状态的实现:

public class Animal
{
    public AnimalType AnimalType;
}

var dog = new Animal();
dog.AnimalType = AnimalType.Dog;

也许还有另一种更好的方法来创建狗的对象,我只是想说明这一点。那么哪种方法更好呢?

创建一个子类允许您定义方法的自定义实现。如果在单个类中使用一个或多个“属性”字段,则会迫使您处理单个位置中属性值的每个可能排列的逻辑。通过使用子类,您可以对功能进行逻辑分组,而不仅仅是属性的另一个组合


另一方面,使用字段来描述类并不一定意味着它是有状态的。如果字段是不可变的(例如,用
final
关键字声明一个原语),您仍然可以避免没有“state”的继承。

您创建了不同的类以具有不同的行为,例如:

public abstract class Animal {
    public abstract void makeASound();
}

public class Dog : Animal {
    public void makeASound() {
        System.out.println("bark, bark!");
    }
}

public class Cat : Animal {
    public void makeASound() {
        System.out.println("mrau, mrau");
    }
}
它们都继承了
Animal
类,因此您可以请求Animal对其进行处理,但您不在乎使用哪种实现

对于类型字段,您必须在条件语句中执行不同的行为

if(animalType == AnimalType.Dog){
    System.out.println("bark, bark!");
} else if(animalType == AnimalType.Cat){
    System.out.println("mrau, mrau!");
}
这将变得很难维持

为什么要养
动物
和其他动物,而不是只养
,其他动物

继承允许您请求一个可以做某事的类,但您不关心这个类到底是如何做的。您可能需要加密一些数据,因此您编写了一个方法,该方法作为参数接受
EncryptionAlgorithm
类并使用它。但是应用程序的用户可以选择不同的算法,因此您可以编写不同的类,如
Rijndael
DES
Serpent
Twofish
,它们都继承了
EncryptionAlgorithm
类,并且都可以作为参数传递给采用
EncryptionAlgorithm
的方法。因此,您不必创建4种方法,如

encryptUsingRijndael(Rijndael algorithm)
encryptUsingTwofish(Twofish algorithm)
encryptUsingDES(DES algorithm)
encryptUsingSerpent(Serpent algorithm)
他们都做同样的事情,但对不同的阶层。您只编写一个方法的

encrypt(EncryptionAlgorithm algorithm)

您可以通过应用程序用户想要使用的任何算法。

这似乎更适合您要我们回答的是整个组合与继承的争论。这是非常广泛的,你最好读一本关于OO设计的书(或一些深入的文章)。在这里,我会使用继承,因为狗不会突然变成猫,所以使用构图没有任何好处(这只会使它很难使用)。@user3580294我如何将问题转移到这里?这正是我发现“积极歧视性”表达“偏好构图而非继承”的原因太令人讨厌了。我认为解决这个问题的方法是将问题标记为mod注意,并声明您希望将其移至程序员SE,但我不是100%确定。。。