У вас может быть фабричный метод, имеющий тип возврата Animal
, но создающий и возвращающий Dog
. Но вы не можете преобразовать Animal
в Dog
после его создания.
Обратите внимание, что истинное преобразование и приведение типов - это не одно и то же. Даже если оператор приведения одинаков для обоих в C #. Если у вас есть переменная Animal a = new Dog();
, вы можете выполнить правильное приведение Dog d = (Dog)a;
. Но a
должен ссылаться на Dog
объект. Если ему присваивается Cat
, то при кастинге возникает исключение.
Лучшее, что вы можете сделать, если вы действительно хотите преобразовать Animal
в Dog
, это добавить конструктор к Dog
, принимая животное в качестве аргумента (C #):
public Dog(Animal a)
{
name = a.name;
age = a.age;
canBark = true;
}
Тогда вы можете создать собаку с:
Animal a = new Animal();
// Initialize animal
Dog dog = new Dog(a);
Но вы не можете сделать это без создания нового объекта. Поэтому создайте правильный тип с самого начала на фабрике:
public class AnimalFactory
{
public static Animal Create(JObject json)
{
string animalType = Get animal type string from json;
Animal a;
switch (animalType) {
case "dog":
var dog = new Dog();
// Fill dog specific stuff.
a = dog;
break;
case "cat":
var cat = new Cat();
// Fill cat specific stuff.
a = cat;
break;
default:
return null;
}
// Fill stuff common to all animals into a.
return a;
}
}
Вероятно, нет смысла создавать экземпляр класса Animal
напрямую. Поэтому я бы объявил это абстрактным.
Вы также можете иметь конструкторы с параметром JObject
в классах животных для делегирования инициализации полей.
public abstract class Animal
{
public Animal(JObject json)
{
// Initialize common fields.
}
public string name;
public int age;
public bool canBark;
}
public class Dog : Animal
{
public Dog(JObject json)
: base(json) // Pass the json object to the Animal constructor
{
// Initialize dog specific fields.
}
}
Завод становится
public class AnimalFactory
{
public static Animal Create(JObject json)
{
string animalType = Get animal type string from json;
switch (animalType) {
case "dog":
return new Dog(json);
case "cat":
return new Cat(json);
default:
return null;
}
}
}