我有以下问题。看看我的代码结构。 如果我的所有派生类在Process(Animal a)中具有相同的方法序列,那么这将是正常的。但想象一下,我有Turtle类,它扩展了Animal,当调用Process(Animal a)时,里面的方法必须按照不同的顺序和类Turtle有一些额外的方法,例如Sleep。 在那种情况下我该怎么办? 感谢
public class Animal
{
public virtual string Eat(){ return "I'm eating"; }
public virtual string MakeNoise() { return "I'm ";}
public virtual string Go() { return "I'm walking"; }
}
public class Dog : Animal
{
public override string Eat()
{
return string.Format("{0} {1}",base.Eat(),"a pie");
}
public override string MakeNoise()
{
return string.Format("{0} {1}",base.MakeNoise(),"barking");
}
}
public class Controller
{
public void Process(Animal a)
{
a.Eat();
a.MakeNoise();
a.Go;
}
}
public class Client
{
IList<Animal> animals= new List<Animal>(){Dog,Cat,Turtle,Mouse}; //all animals have base class Animal
Controller = new Controller();
foreach(Animal a in animals)
{
p.Process(a);
}
}
答案 0 :(得分:2)
您可以添加重载方法
public void Process(Turtle t)
{
//Do what you want here
}
答案 1 :(得分:0)
您可以自己编写一个控制器工厂,它将为给定的动物返回适当的控制器。为Turtle创建一个Controller子类等。这里我假设我们可以提取一个接口IControler和IAnimal,但你可以使用抽象基类型。
public class ControllerFactory
{
public static IController GetController (IAnimal animalToControl)
{
if (animalToControl is Turtle) { return new TurtleController(); }
if (animalToControl is Sheep) { return new SheepController(); }
// default
return new Controller();
}
}
并致电:
foreach(Animal a in animals)
{
var p = ControllerFactory.GetController(a);
p.Process(a);
}
这里的工厂实施很粗糙,但说明了这一点。
答案 2 :(得分:0)
每只动物都有Eat
,MakeNoise
和Go
,但序列因动物而异(加上某些动物的一些额外行为。)序列总是相同的给动物?这是他们从Animal
继承的唯一原因,以便他们可以共享相同的基本行为,并且只在需要时才覆盖?
如果是这样,那么控制器中的Process
方法可能代替ExecuteBehaviors
方法,Animal
上的public virtual void ExecuteBehaviors()
{
Eat();
MakeNoise();
Go();
}
方法可以被个别动物覆盖。
ExecuteBehavior
然后如果动物需要不同的序列,它可以覆盖该方法。 这似乎符合你的问题的描述,允许每个动物继承行为但控制它们的顺序并添加新的行为。
然后在您的控制器中,您可以为每只动物调用Animal
。这是工作中真正的多态性。您可以将Dog
的任何实例视为相同,并在其上调用相同的方法,无论它是Turtle
还是@Transactional
@EnableTransactionManagement
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
@DeclareRoles("Security Admin")
public class SecurityServiceBean
{
@Override
@PermitAll
public UserRegistration confirmRegistration(
String confirmationCode) throws ApplicationException
{
try
{
QueryResults<UserRegistration> userRegistrations = this.userRegistrationDAO
.find(new UserRegistrationQuery(null, confirmationCode));
if (userRegistrations.getTotalRecords() == 1)
{
UserRegistration userRegistration = userRegistrations.uniqueResult();
if (userRegistration.getConfirmationDate() == null)
{
userRegistration.setConfirmationDate(new Date());
userRegistration.setState(State.CONFIRMED);
userRegistration = this.userRegistrationDAO.saveOrUpdate(userRegistration);
...
}
...
}
}
}
}
,即使它们的行为会有所不同。
答案 3 :(得分:0)
您有两个选项,第一个是扩展Process方法。你可以在里面进行切换,并在a.GetType()== typeof(Turtle)时定义顺序。
public class Controller
{
public void Process(Animal a)
{
if(a.GetType() == typeof(Turtle)
{
((Turtle)a).YourMethod();
}
else
{
a.Eat();
a.MakeNoise();
a.Go;
}
}
}
或者您可以让Animal类负责Process方法。 我认为这里的想法并不是让Animal类负责Process方法。这就是Controller的行动。尝试为每个动物使用装饰器模式或工厂,如@Brett所说