我向在大学学习该课程的学生讲授Java编程语言的基础知识。
今天,其中一个让我对她的问题感到非常困惑,所以我告诉她只给我一天时间来思考这个问题,然后我会尽可能准确地给她一个答案。
她告诉我,老师instanceof
在考试中使用关键字时非常生气。
她还说,老师说,如果使用该词,就无法证明多态性是如何工作的。
我花了很多时间试图找到一种方法来证明在某些情况下我们需要使用instanceof
,并且即使我们使用它,该方法中仍然存在一些多态性。
所以这是我做的例子:
public interface Animal
{
public void talk();
}
class Dog implements Animal {
public void talk() {
System.out.println("Woof!");
}
}
public class Cat implements Animal
{
public void talk() {
System.out.println("Meow!");
}
public void climbToATree() {
System.out.println("Hop, the cat just cimbed to the tree");
}
}
class Hippopotamus implements Animal {
public void talk() {
System.out.println("Roar!");
}
}
public class Main {
public static void main(String[] args) {
//APPROACH 1
makeItTalk(new Cat());
makeItTalk(new Dog());
makeItTalk(new Hippopotamus());
//APPROACH 2
makeItClimbToATree(new Cat());
makeItClimbToATree(new Hippopotamus());
}
public static void makeItTalk(Animal animal) {
animal.talk();
}
public static void makeItClimbToATree(Animal animal) {
if(animal instanceof Cat) {
((Cat)animal).climbToATree();
}
else {
System.err.println("That animal cannot climb to a tree");
}
}
}
我的结论如下:
第一种方法(APPROACH 1)是关于如何对接口进行编程的简单演示,而不是实现。我认为makeItTalk(Animal animal)
通过使用动物对象,在方法的参数中以及在方法对话的调用方式中,多态性清晰可见。(这部分是可以的)
第二部分使我感到困惑。她instanceof
在考试中的某个时候使用了(我不知道他们的考试是什么样子的),但由于老师说你不是在证明多态性,所以未被正确接受。
为了帮助她了解何时可以使用instanceof
,我想告诉她可以使用它,只要她需要调用的方法不在接口中,而只是在实现类之一中。
如您所见,只有猫可以爬到树上,而让河马或狗爬到树上是不合逻辑的。我认为这可能是何时使用的一个例子instanceof
但是方法2中的多态性呢?
您在那里看到了多态性的几种用途(仅方法2)?
您是否认为此行中包含某种类型的多态性?
((Cat)animal).climbToATree();
我认为是可以的,因为为了实现这种Casting,对象需要具有IS-A关系,某种程度上是多态的。
您如何看待,对吗?
如果是,您将如何用自己的话来解释这种转换依赖于多态性?
在上面的示例中,无需致电
makeItClimbToATree (new Hippopotamus ());
如果makeItClimbToATree不会指望动物,而是更具体的东西,它确实能够爬上树,则可以很容易地避免这种情况。允许动物并因此使用instanceof的必要性并不明显。如果在动物列表中管理动物,则将更加明显。
尽管ircmaxells的解释开始很好,在介绍考拉和其他TreeClimbers时,他没有看到隐藏在海葵中的第二种扩展:不同的动物功能,例如seaAnemoneHider,winterSleeping,blueEyed,bugEating等,等等。 。您将得到布尔值而不是布尔值,不断地重新编译基类,并破坏扩展的客户类,这将需要再次重新编译,并且无法以类似的方式介绍自己的可能性。
客户A将需要客户B声明NotBugEatingException,以将您的行为纳入基类。
引入自己的接口并结合instanceof,是一种更简洁,更灵活的方法。顾客A可能定义了不喜欢动物的潜水,象企鹅B和顾客B那样大声疾呼,既不影响动物类别,又不引起无用的重新编译。
import java.util.*;
interface Animal {
public void talk ();
}
interface TreeClimbing {
public void climbToATree ();
}
class Dog implements Animal {
public void talk () { System.out.println("Woof!"); }
}
class Cat implements Animal, TreeClimbing {
public void talk () { System.out.println("Meow!"); }
public void climbToATree () { System.out.println ("on top!"); }
}
public class TreeCriterion {
public static void main(String[] args) {
List <Animal> animals = new ArrayList <Animal> ();
animals.add (new Cat ());
animals.add (new Dog ());
discuss (animals);
upTheTree (animals);
}
public static void discuss (List <Animal> animals) {
for (Animal a : animals)
a.talk ();
}
public static void upTheTree (List <Animal> animals) {
for (Animal a : animals) {
if (a instanceof TreeClimbing)
((TreeClimbing) a).climbToATree ();
}
}
}
我们不需要第三只动物,狗和猫就足够了。我使它们默认可见而不是公开,以使整个示例适合单个文件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句