对多态性的使用有疑问,也对多态性与铸造有什么关系?

发布于 2024-11-14 08:09:55 字数 2288 浏览 3 评论 0原文

我为在大学学习该主题的学生讲授 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) 的参数中,以及在调用方法 talk 的方式中,通过使用animal object.(这部分没问题)

  • 第二部分是让我困惑的部分。她在考试中的某个时刻使用了 instanceof (我不知道他们的考试是什么样的),但没有被正确接受,因为老师说,你没有证明多态性。

为了帮助她理解何时可以使用 instanceof,我考虑告诉她,当她需要调用的方法不在接口中,而只是在其中一个方法时,她可以使用它。实施类。

正如您所看到的,只有猫可以爬到树上,而让河马或狗爬到树上是不合逻辑的。我认为这可能是何时使用 instanceof

  • 但是方法 2 中的多态性怎么样?

  • 您在那里看到了多少多态性的用途(仅方法 2)?

  • 你认为这条线有某种类型的多态性吗?

    ((Cat)animal).climbToATree();

我认为确实如此,因为为了实现这种类型的强制转换,对象需要具有 IS-A 关系,在某种程度上是多态性。

  • 您认为,这是正确的吗?

  • 如果是,你会如何用自己的话解释,转换依赖于多态性?

I give lessons on the fundamentals of the Java programming language, to students who study this subject in college.

Today one of them got me really confused with her question, so I told her to give me just a day to think about the problem, and I'll give her as accurate of an answer as I can.

She told me that the teacher got really angry when she used the keyword instanceof in her exam.

Also, she said that the teacher said that there is not a way to prove how polymorphism worked if she used that word.

I thought a lot to try to find a way to prove that in some occasions we need to use instanceof, and also that even if we use it, there still some polymorphism in that approach.

So this is the example I made:

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");
        }
    }
}

My conclusions are the following:

  • The first approach (APPROACH 1) is a simple demo of how to program to an interface, not a realization. I think that the polymorphism is clearly visible, in the parameters of the method makeItTalk(Animal animal), and also in the way the method talk is called, by using the animal object.(This part is ok)

  • The second part is the one that makes me confused. She used instanceof at some point in her exam (I don't know how their exam looked like), and that was not accepted correctly because the teacher said, you are not proving polymorphism.

To help her understand when she can use instanceof, I thought about telling her, that she can use it, when the method she needs to call is not in the interface, but it is just in one of the implementing classes.

As you can see, only cats can climb to trees, and it would not be logical to make a Hippopotamus or a Dog climb to a tree. I think that could be an example of when to use instanceof

  • But what about polymorphism in approach 2?

  • How many uses of polymorphism do you see there (only approach 2)?

  • Do you think this line has some type of polymorphism in it?

    ((Cat)animal).climbToATree();

I think it does, because in order to achieve a Casting of this type, the objects need to have an IS-A relationship, an in some way that is polymorphism.

  • What do you think, is it correct?

  • If yes, how would you explain with your own words, that casting relies on polymorphism?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

就是爱搞怪 2024-11-21 08:09:55

instanceof 方法被视为不好的原因很简单。猫并不是唯一能够爬树的动物

如果以后您需要添加 Koala 类,会发生什么情况?那么简单的 if 就变成了不那么简单的 or。那么,当您添加另一个类时会发生什么?还有另一个。还有另一个。这就是 instanceof 被认为不好的主要原因。因为它将实现耦合到一个具体的类,而不是打开它让被调用者确定要做什么。

只需实现 makeItClimbToATree() 方法即可在对无法攀爬的动物调用时抛出 CantClimbTreesException 。这样您就可以两全其美。易于实施,且易于扩展。

恕我直言,instanceof 只有 1 个真正有效的用途:在测试用例中测试方法返回的实例与预期返回类型是否匹配(在非类型安全语言中)。

基本上任何其他用途都很可能被重构或以不同的方式设计以消除其使用的需要。

另一种看待它的方式是:多态性允许您从代码中消除几乎所有条件语句。唯一无法摆脱的条件(至少是所有条件)是在对象创建方法中(例如在工厂中,它必须根据运行时参数选择类)。几乎任何其他条件都可以被多态性取代。因此,任何执行条件执行的东西根据定义都是反多态的。这并不是说它很糟糕( 好并且足够好),但在学术讨论中,它不是多态的......

永远不要忘记 60/60 规则。总开发时间的 60% 将用于维护所编写的代码,而 60% 的时间将用于添加新功能。让维护变得更容易,您的生活也会更轻松。这就是 instanceof 不好的原因。它使初始设计更容易,但使长期维护变得复杂(无论如何更昂贵)......

The reason the instanceof method is seen as bad is simple. Cats aren't the only Animal that might be able to climb a tree.

What happens if down the road you need to add a Koala class. Then your simple if becomes a not so simple or. Then, what happens when you add another class? and another one. And another one. That's the prime reason why instanceof is seen as bad. Because it couples the implementation to a concrete class, rather than opening it for the callee to determine what to do.

Simply implement the makeItClimbToATree() method to throw a CantClimbTreesException if called on an animal that can't climb. That way you have the best of both worlds. Easy to implement, and easy to extend.

IMHO, instanceof has only 1 truly valid use: In a test case to test the returned instance from a method matches the expected return type (in non-type safe languages).

Basically any other use can more than likely be refactored away or designed differently to negate the need for its use.

Another way to look at it is this: Polymorphism allows you to eliminate almost all conditional statements from your code. The only conditionals that you can't get rid of (at least all of them) are in object creational methods (such as in a factory where it must choose the class based upon a runtime argument). Just about any other conditional can be replaced by polymorphism. Therefore, anything that does conditional execution is by definition anti-polymorphic. That's not to say it's bad (there's a huge difference between Good and Good Enough), But in an academic discussion, it's not polymorphic...

Never forget the 60/60 rule. 60% of your total development time will be spent maintaining the code you wrote, and 60% of that time will be spent adding new features. Make maintaining easier, and your life will be easier as well. That's why instanceof is bad. It makes the initial design easier, but complicates the long term maintenance (which is more expensive anyway)...

明明#如月 2024-11-21 08:09:55

在上面的示例中,无需调用

makeItClimbToATree (new Hippopotamus ());

它可以轻松避免,如果 makeItClimbToATree 不需要动物,而是更具体的东西,它确实能够爬树。允许动物的必要性,以及因此使用instanceof的必要性,是不可见的。如果你用动物列表来管理动物,那就更明显了。

虽然 ircmaxell 的解释开头很好,但在介绍考拉和其他爬树者时,他没有看到隐藏在海葵中的第二个扩展:动物的不同能力,如海葵隐藏者、冬眠、蓝眼、吃虫等等,等等。您最终会得到布尔值超过布尔值,不断重新编译基类,以及破坏扩展客户类,这将需要再次重新编译,并且无法以类似的方式引入它们自己的可能性。

客户 A 需要客户 B 声明 NotBugEatingException,以将您的行为放入基类中。

引入您自己的接口,并与instanceof 相结合,是一种更简洁的方法,也更灵活。客户 A 可能定义了潜水LikeAPenguin,而客户 B 则大肆宣扬,两者互不了解,既不会影响 Animal 类,也不会引发无用的重新编译。

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 ();
        }
    }
}

我们不需要第三种动物,狗和猫就足够了。我将它们设置为默认可见而不是公开,以使整个示例适合单个文件。

In your above example, there is no need to call

makeItClimbToATree (new Hippopotamus ());

It could be easily avoided, if makeItClimbToATree wouldn't expect an animal, but something more specific, which is really able to climb a tree. The necessity to allow animals, and therefore to use instanceof, isn't visible. If you manage the animals in a List of animals, it will be more obvious.

While ircmaxells explanation starts great, while introducing the Koala and other TreeClimbers, he doesn't see a second extension which is hiding in a sea anemone: different capabilities of animals like seaAnemoneHider, winterSleeping, blueEyed, bugEating, and so on, and so on. You would end up with boolean over boolean, constantly recompiling the base class, as well as breaking extending customer classes, which would need recompilation again, and wouldn't be able to introduce their own possibilities in a similar manner.

Customer A would need Customer B to declare a NotBugEatingException, to get your behaviour into the base class.

Introducing your own interfaces, combined with instanceof, is a much cleaner approach, and more flexible. Customer A might define divingLikeAPenguin and customer B trumpeting, both not knowing of each other, both not affecting the Animal class and not provoking useless recompilations.

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 ();
        }
    }
}

We don't need a third animal, dog and cat are enough. I made them default visible instead of public, to make the whole example fit into a single file.

茶底世界 2024-11-21 08:09:55

你认为这条线有某种类型的多态性吗?

((Cat)animal).climbToATree();

不。特别是,因为 Cat 是示例中的叶类。

我认为确实如此,因为为了实现这种类型的强制转换,对象需要具有 IS-A 关系,在某种程度上就是多态性。

多态性需要 IS-A 关系,但反之则不然。

多态性是指您基于抽象接口分派(可能)不同的方法。如果您没有这种调度,那么它就没有使用多态性。在您的示例中,使用 instanceof 转换为没有子类的类,您将不再需要调度。

(当然,在 Java 中“实现多态性”的方法不止一种。您可以使用接口、使用抽象类或使用带有子类的具体类……或将来可能编写的假设子类来实现它。接口(以及基于接口的调度)通常是最好的方法,因为它们将 API 与类的身份完全分离。)

另外,使用 instanceof 就像这样 通常是糟糕设计和/或糟糕建模的标志。具体来说,它硬连接了只有猫可以攀爬的假设,如果我们将其他动物纳入模型/程序中,这个假设就很容易被证伪。如果发生这种情况,你的代码就会崩溃。

Do you think this line has some type of polymorphism in it?

((Cat)animal).climbToATree();

No. Especially, since Cat is a leaf class in the example.

I think it does, because in order to achieve a Casting of this type, the objects need to have an IS-A relationship, an in some way that is polymorphism.

Polymorphism requires the IS-A relationship, but not the other way round.

Polymorphism is when you dispatch to (potentially) different methods based on an abstract interface. If you don't have that dispatching, then it is not using polymorphism. In your example, using instanceof to cast to a class with no subclasses, you are removing the need for dispatching.

(Of course, there is more than one way to "do polymorphism" in Java. You can implement it using interfaces, using abstract classes, or using concrete classes with subclasses ... or hypothetical subclasses that may be written in the future. Interfaces (and dispatching based on an interface) are generally the best way because they give a clean separation of the API from the identity of class.)

And on a separate note, using instanceof like that is typically a sign of poor design and / or poor modelling. Specifically, it hard-wires the assumption that only cats can climb, which is trivially falsified if we include other animals into the model / program. If that happens, your code breaks.

千秋岁 2024-11-21 08:09:55

也许我没有抓住要点,没有理解考试问题的上下文,但是 Animal 是否可以爬树应该是实现 Animal 的类的一部分>。例如,如果 Animal 是一个接口,您可以有一个方法 boolean isCapableOfClimbing(),然后每个实现类都能够指示其功能。

尝试让动物攀爬的方法可以使用它。对于试图让动物爬树检查它是否是特定类的实例的方法来说是没有意义的,因为该方法指定了应该在实现类中指定的内容。简单的方法不应为其所使用的类提供行为。

至于何时使用 instanceof 的问题,几乎总是使用它的地方是重写类的 equals() 方法,因为它只接受Object,您通常必须确保它具有相同的类型,以便可以对其进行强制转换,然后进行有意义的比较。

Maybe I'm missing the point and don't get the context of the exam question, but whether an Animal can climb a tree should be a part of the class that implements Animal. For example, if Animal is an interface, you could have a method boolean isCapableOfClimbing() and then each implementing class would be able to indicate its capability.

A method that attempted to make the animal climb could then use that. It doesn't make sense for a method that's trying to make the animal climb a tree check whether it's an instance of a particular class, since then that method is specifying something that should be specified in the implementing class. A simple method should not provide behaviour for a class that it's using.

As for your question of when to use instanceof, once place where it will almost always be used is if overriding the equals() method of a class, since it only accepts an Object and you typically have to ensure it is of the same type so it can be cast and then meaningfully compared.

像你 2024-11-21 08:09:55

像下面的代码怎么样?它通过将爬树分离为您可以在动物上实现或不实现的另一个接口来解决通用性问题。它更适合这个问题:爬树并不是所有动物的固有属性,而只是其中一部分动物的固有属性。至少对我来说,它看起来比抛出 NotImplementedException 更清晰和优雅。


public interface Animal {
    public void talk();
}

public interface AnimalCanClimbTrees extends Animal {
    public void climbToATree();
}

public class Dog implements Animal {
    public void talk() {
        System.out.println("Woof!");
    }
}
/* Animal is probably not needed, but being explicit is never bad */
public class Cat implements Animal, AnimalCanClimbTrees 
{
    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 AnimalCanClimbTrees) {
           ((AnimalCanClimbTrees)animal).climbToATree();                  
       }
       else {
           System.err.println("That animal cannot climb to a tree");
       }
   }
}

What about something like the code below? It solves the generality problem by separating the tree-climbing as another interface you can implement or not on your animals. It fits the problem better: climbing trees is not an intrinsic property of all animals, only of a subset of them. At least to me it looks much clearer and elegant than throwing NotImplementedExceptions.


public interface Animal {
    public void talk();
}

public interface AnimalCanClimbTrees extends Animal {
    public void climbToATree();
}

public class Dog implements Animal {
    public void talk() {
        System.out.println("Woof!");
    }
}
/* Animal is probably not needed, but being explicit is never bad */
public class Cat implements Animal, AnimalCanClimbTrees 
{
    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 AnimalCanClimbTrees) {
           ((AnimalCanClimbTrees)animal).climbToATree();                  
       }
       else {
           System.err.println("That animal cannot climb to a tree");
       }
   }
}
怀中猫帐中妖 2024-11-21 08:09:55

instanceof 运算符与多态性无关。它只是用于查看对象是否是特定类的实例。您会看到此运算符在 equals() 方法中被大量使用,因为该方法采用泛型 Object 作为参数:

public class Cat implements Animal{
  @Override
  public boolean equals(Object obj){
    if (obj == null || !obj instanceof Cat){
      //obj is null or not a "Cat", so can't be equal
      return false;
    }
    if (this == obj){
      //it's the same instance so it must be equal
      return true;
    }
    Cat catObj = (Cat)obj; //cast to "Cat"
    return this.getName().equals(catObj.getName()); //compare the two objects
  }
}

如果类没有实现方法,则它应该抛出异常。我相信您应该抛出的“官方”异常是UnsupportedOperationException。为了“正确”,我认为 Animal 接口应该有一个 public voidclimbToATree(); 方法。 DogHippo 类中的 climbToATree() 方法应抛出 UnsupportedOperationException,因为它们无法实现此方法。但是,如果您经常抛出此异常,那么您的对象模型可能有问题,因为我认为这不是常见的事情。

另请注意,在 Java 中的多态编程中使用 @Override 注释很有帮助(但不是必需)。如果带有此注释的方法没有重写父方法、实现抽象方法或(在 Java 6 中)实现接口方法,这将导致抛出编译错误。这可以帮助捕获您在方法签名中犯的任何错误。例如:

public String tostring(){
  return "foobar";
}

如果没有注释,程序可以编译并运行成功。但这不是你的本意!您想重写 toString(),但您不小心将名称拼写错误!

The instanceof operator has nothing to do with polymorphism. It is simply used to see whether or not an object is an instance of a particular class. You see this operator being used a lot in the equals() method, because the method takes a generic Object as a parameter:

public class Cat implements Animal{
  @Override
  public boolean equals(Object obj){
    if (obj == null || !obj instanceof Cat){
      //obj is null or not a "Cat", so can't be equal
      return false;
    }
    if (this == obj){
      //it's the same instance so it must be equal
      return true;
    }
    Cat catObj = (Cat)obj; //cast to "Cat"
    return this.getName().equals(catObj.getName()); //compare the two objects
  }
}

If a class does not implement a method, then it should throw an exception. I believe the "official" exception you are supposed to throw is UnsupportedOperationException. To be "correct", I think the Animal interface should have a public void climbToATree(); method. The climbToATree() methods in the Dog and Hippo classes should throw an UnsupportedOperationException because they cannot implement this method. But if you are throwing this exception very often, then there may be something wrong with your object model, as this is not a common thing to do I don't think.

Also note that it's helpful (but not required) to use the @Override annotation with polymorphic programming in Java. This will cause a compilation error to be thrown if a method with this annotation does not override a parent method, implement an abstract method, or (in Java 6) implement an interface method. This can help catch any mistakes you make in the method signature. For example:

public String tostring(){
  return "foobar";
}

Without the annotation, the program would compile and run successfully. But this was not your intention! You wanted to override toString(), but you accidentally spelled the name wrong!!

誰認得朕 2024-11-21 08:09:55

我很惊讶没有人写任何有关后期绑定的文章。 Java 中的多态性 = 后期绑定。当我们最终知道对象的类型时,被调用的方法将被附加到对象上。在您的示例中:

 if(animal instanceof Cat) {
     ((Cat)animal).climbToATree();                  
 }

您正在 Cat 对象上调用 climbToATree() ,以便编译器接受它。在运行时,无需检查调用对象的类型,因为 climbToATree() 仅属于 Cat。因此这些代码行不存在多态性。

关于铸造与多态性相关,事实并非如此。如果强制转换合法,则强制转换仅限制两个对象中共享的字段。您可以这样做:

class A {
    int getInt() {}
}

class B extends A {
    int getInt() {}
}

// in main
A a = new B();
A b = (A)a;
b.getInt(); // This would still call class B's getInt();

强制转换本身不添加任何值,getInt() 在运行时绑定到 a 的运行时类型,即 B 类。

I'm surprised no one wrote anything about Late Binding. Polymorphism in Java = Late Binding. The method being called will be be attached to the object when we finally know its type. In your example:

 if(animal instanceof Cat) {
     ((Cat)animal).climbToATree();                  
 }

You are calling climbToATree() on a Cat object so the compiler accepts it. At run time, there is no need to check the type of the calling object since climbToATree() belongs to Cat only. And so there is no polymorphism in these lines of code.

About casting being related to Polymorphism, it isn't. Casting just limits the fields that are shared in both objects, if the cast is legal. You could do this:

class A {
    int getInt() {}
}

class B extends A {
    int getInt() {}
}

// in main
A a = new B();
A b = (A)a;
b.getInt(); // This would still call class B's getInt();

The cast itself added no value, getInt() was bound at run time to the runtime type of a, which was class B.

晚风撩人 2024-11-21 08:09:55

多态和 OOP 方法是将方法 makeItClimbToATree 放在 Animal 接口上:

public interface Animal{    
    public void talk(); 
    public void makeItClimbToATree();  
}

然后 Animal 的实现者将提供该方法的行为,对于除 Cat 之外的所有方法都可能抛出异常。这是多态的,因为您可以通过单个方法操作 Animal 的不同实现。

使用instanceOf 运算符的函数被认为是“坏”OOP,因为它需要了解所有实现类型才能确定方法的行为。

A polymorphic and OOP approach would be to place the method makeItClimbToATree on the Animal interface:

public interface Animal{    
    public void talk(); 
    public void makeItClimbToATree();  
}

Then the implementors of Animal would provide the behavior for the method, which for all other than Cat could be to throw an exception. This is polymorphic because you operate on different implementations of Animal through a single method.

The function which uses the instanceOf operator is considered "bad" OOP because it requires knowledge of all the implementation types to determine the behavior of the method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文