C# 是否可以从基类构造函数创建派生类?
我有三门课,动物,猫和狗C# 是否可以从基类构造函数创建派生类?,c#,inheritance,polymorphism,C#,Inheritance,Polymorphism,我有三门课,动物,猫和狗 // calling code var x = new Animal("Rex"); // would like this to return a dog type var x = new Animal("Mittens"); // would like this to return a cat type if(x.GetType() == typeof(Dog)) { x.Bark(); } else { x.Meow(); } class Anima
// calling code
var x = new Animal("Rex"); // would like this to return a dog type
var x = new Animal("Mittens"); // would like this to return a cat type
if(x.GetType() == typeof(Dog))
{
x.Bark();
}
else
{
x.Meow();
}
class Animal
{
public Animal(string name)
{
// check against some list of dog names ... find rex
// return Animal of type Dog.
// if not...
// check against some list of cat names ... find mittens
// return Animal of type Cat.
}
}
这有可能吗?如果没有,我能做些类似的事情吗?您要找的是“虚拟构造函数”(C#中不可能)或工厂模式
class Animal
{
// Factory method
public static Animal Create(string name)
{
Animal animal = null;
... // some logic based on 'name'
animal = new Zebra();
return animal;
}
}
Factory方法也可以放在另一个(Factory)类中。这提供了更好的解耦等。不。基本上正确的解决方法是使用静态方法,该方法可以创建正确类型的实例:
var x = Animal.ForName("Rex");
var x = Animal.ForName("Mittens");
...
public abstract class Animal
{
public static Animal ForName(string name)
{
if (dogNames.Contains(name))
{
return new Dog(name);
}
else
{
return new Cat(name);
}
}
}
或者这可能是AnimalFactory
类型(或其他类型)中的实例方法。这将是一种更具扩展性的方法——例如,工厂可以实现一个接口,并且可以注入到创建实例所需的类中。不过,这确实取决于上下文——有时这种方法有些过头了
基本上,
newfoo(…)
调用总是准确地创建Foo
的实例。然而,使用返回类型Foo
声明的静态方法可以返回对与Foo
兼容的任何类型的引用。不,我认为这是不可能的
您可以创建一个静态类,该类有一个基于名称返回动物的方法,例如
static Animal CreateAnimal(string name)
{
if(catList.Contains(name))
return new Cat(name");
else if(dogList.Contains(name))
return new Dog(name);
return null;
}
其他答案表明,您需要使用工厂模式,但我想给您一个更“实际”的示例,说明如何使用工厂模式。我做的和你们做的完全一样,但我和你们一起工作。当我看到
X
时,我需要创建类Rectangle
的实例,当我看到a
时,我需要创建类Text
的实例
(我写了这篇文章,因此我确信我所做的一些事情可以改进)
DrawableItemBase
:
public abstract class DrawableItemBase : Epl2CommandBase, IDrawableCommand
{
protected DrawableItemBase()
{
Location = new Point();
}
protected DrawableItemBase(Point location)
{
Location = location;
}
protected DrawableItemBase(int x, int y)
{
Location = new Point();
X = x;
Y = y;
}
private Point _Location;
[XmlIgnore]
public virtual Point Location
{
get { return _Location; }
set { _Location = value; }
}
[XmlIgnore]
public int X
{
get { return _Location.X; }
set { _Location.X = value; }
}
[XmlIgnore]
public int Y
{
get { return _Location.Y; }
set { _Location.Y = value; }
}
abstract public void Paint(Graphics g, Image buffer);
}
public abstract partial class Epl2CommandBase : IEpl2Command
{
protected Epl2CommandBase() { }
public virtual byte[] GenerateByteCommand()
{
return Encoding.ASCII.GetBytes(CommandString + '\n');
}
public abstract string CommandString { get; set; }
}
Epl2CommandBase
:
public abstract class DrawableItemBase : Epl2CommandBase, IDrawableCommand
{
protected DrawableItemBase()
{
Location = new Point();
}
protected DrawableItemBase(Point location)
{
Location = location;
}
protected DrawableItemBase(int x, int y)
{
Location = new Point();
X = x;
Y = y;
}
private Point _Location;
[XmlIgnore]
public virtual Point Location
{
get { return _Location; }
set { _Location = value; }
}
[XmlIgnore]
public int X
{
get { return _Location.X; }
set { _Location.X = value; }
}
[XmlIgnore]
public int Y
{
get { return _Location.Y; }
set { _Location.Y = value; }
}
abstract public void Paint(Graphics g, Image buffer);
}
public abstract partial class Epl2CommandBase : IEpl2Command
{
protected Epl2CommandBase() { }
public virtual byte[] GenerateByteCommand()
{
return Encoding.ASCII.GetBytes(CommandString + '\n');
}
public abstract string CommandString { get; set; }
}
各种接口:
public interface IEpl2GeneralFactoryProduct
{
string GetFactoryKey();
}
public interface IEpl2Command
{
string CommandString { get; set; }
}
public interface IDrawableCommand : IEpl2Command
{
void Paint(System.Drawing.Graphics g, System.Drawing.Image buffer);
}
事实上没有限制你自己。。。您的基类需要知道它的子类,这不是很有用。