如果我有Cat和Dog类来实现PetBase。他们每个人都拥有一个名为Owner的对象。并且所有者拥有一个名为Emotion的对象。我如何限制访问Emotion类中的某些属性或函数或函数参数,具体取决于它是属于Cat还是Dog?像这样:
Dog d = new Dog();
d.Owner.Emotion.SetFearLevel(10); // dog owners can have a fear level from 1-10 so let the user decide.
Cat c = new Cat();
c.Owner.Emotion.SetFearLevel(); // all cat owners have the same fear level so I don't want the user to be able to pass in a parameter but still be able to call SetFearLevel(). How do I enforce this?
在这个例子中,我想限制Cat所有者能够将参数传递给SetFearLevel(),但是让狗主人可以灵活地想要他们想要的(即能够传入一个SetFearLevel()的参数。
我需要在设计中做些什么改变?
[ 修改
这是Jordao和DavidFrancis的回答之间的折腾。最后,由于应用程序的树结构特性,我选择了DavidFrancis的设计。
答案 0 :(得分:1)
SetFearLevel是一个不同的签名,因此您需要两种基本情感类型的不同子类型 那么每个宠物类型都需要一个单独的所有者子类型 返回类型通常可以是Covariant(即子类型),因此每个所有者子类型都可以返回适用于该所有者的特定Emotion子类型。
答案 1 :(得分:1)
您可以封装对类本身所需功能的访问权限:
dog.setOwnerFearLevel(5);
cat.setOwnerFear();
请小心使用Demeter变形镜。
答案 2 :(得分:0)
你的联系是错误的。您想从owner.SetFearLevel(5)
开始。所有者owner
必须了解他/她自己的宠物和他/她自己的情绪。因此,该方法可以检查“我有猫还是狗?”然后正确地设置它的情感实例:“我不害怕发现5的参数(因为我拥有一只猫)。”或者换句话说,主人引用宠物,而不是宠物主人。
为了更清楚地看到这一点,请注意您的模型很容易让一个人拥有任意数量的狗和猫。你总是可以创造一个新宠物,让这个倒霉的人成为主人。这可能很有用,但它使计算他/她的恐惧程度相当复杂。从某种意义上说,这几乎是不可能的,因为,对于任何给定的宠物,你知道主人,给予任何主人你不知道宠物。 (我承认,这是一个容易解决的问题。)
因此,在Owner类中引用宠物(或宠物 - 可能使用最大恐惧因子)并将SetFearLevel方法从Emotion类移动到Owner类,并且所有内容都应该很好地结合在一起。