我理解压倒一切的作用及其作用。我不明白的是,如果课程设计“正确”,为什么有人需要使用它?
例如,假设我有一个名为Animal的类,我添加了一个说话方法。然后,我有几个继承动物的课程,如牛,狗和猫。但这些“说话”中的每一个都不同。奶牛做:system.out.println(“moo”)。狗做“woof”,猫做“喵”。
我的问题是,如果奶牛,狗和猫都必须覆盖说话方法,那为什么我甚至会首先在动物课上说话呢?
我尝试在线和Stackoverflow上研究原因,但似乎没有人给我一个具体的答案。我最好的是我应该真正使用一个接口(来自声称从具体类扩展的帖子是EVIL)。
答案 0 :(得分:5)
一个答案是多态性。
在Animal
级别定义发言时,它允许我这样做。
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Dog("Charlie"));
animals.add(new Bird("Tweety"));
animals.add(new Duck("Cheese and Quackers"));
for( Animal a : animals )
a.speak();
由于speak具有在基类中定义的基本行为,我可以保证会有一些说话行为,所以我可以从基类调用该行为安全,而不会有调用不存在的方法的风险一类。如果特定类具有更复杂的实现,这很好,但我至少保证有一些实现。我不想担心如果Giraffe
没有实施发言 - 通过扩展已经定义了最小例程的动物,通过合同我保证有一些实现我可以使用。
您也可以使用接口完成此操作,但是有些情况下接口不如扩展,因为接口要求所有实现类都有自己的实现,这在很多情况下是浪费时间。
这让我得到了第二个答案:简单。
你说(释义)&#39;如果所有对象都必须实现说话而且所有人都说不同的话#39;这是一个很大的假设。如果90%的动物说话相同而只有一些动物说话不同怎么办?考虑Monkey
,Human
,Cat
和Telepathic Cat
。在这里,我可能会争辩说前三个会说同样的话。唯一需要自己说话的人是Telepathic Cat
,因为它使用不同的方法来说话。在这种情况下,它定义的有用只说两次。一次进入Animal
,第二次进入Telepathic Cat
的特殊情况。这使代码维护变得更加简单。如果每个人的发言都是真正不同的话,那么也许你想要一个界面,但如果大多数动物说话都相同,那么继承就赢得了胜利。
答案 1 :(得分:3)
如果Animal没有speak()方法,那么如果你这样做了
func palletViewConstraint(inputView: UIView, groups: [UIView], blockTitles: [[String]]){
//Do this so the count is not recalculated each for loop
let blockTitlesCount = blockTitles.count
for i in blockTitlesCount {
let subArrCount = blockTitles[i].count
//The rest of your palletViewConstraint Code that references subArrCount
}
}
你做不到
func palletViewConstraint(inputView: UIView, groups: [UIView], blockTitles: [[String]]){
var countArr = [Int]()
arr.map { (subArr) in
countArr.append(subArr.count)
}
for count in countArr {
//Your code referencing the count of each subArr
}
}
即使Dog有Animal a = new Dog();
方法
答案 2 :(得分:1)
就这样,当你有一个Animal实例时,你会确信它可以说()。这就是合同设计的原则。动物类(合同)向您保证任何兄弟都能说话。事实上,任何兄弟姐妹都有自己的方式,这就是多态性。
对于你的副问题,我理解为什么会在接口上使用抽象方法 - 当你有某种标准方法或默认方式在父类中实现方法时它会很有用,即使你没有在那里完全实现它的能力,抽象方法与常规方法的不同之处在于它将强制子类实现该方法,就像接口一样。
答案 3 :(得分:1)
通常,在您的情况下,像Animal类这样的抽象类旨在为Animal的所有子类提供特定的接口。 Animal的抽象部分允许程序员意识到他必须为speak
创建一个方法。毕竟,每个动物的说法都不同,动物说话没有“默认”的方式。
答案 4 :(得分:0)
这就是面向对象编程的本质,在你所采用的例子中。动物是一个原型(理想情况下应该是你的界面),它定义了动物的特征。这意味着你称之为动物的任何东西都应具备这些功能。这就是你如何将所有动物绑定为动物类型。从设计的角度来看,你会得到一幅清晰的画面。