【问题标题】:Difference between inheritance and polymorphism继承和多态的区别
【发布时间】:2012-06-11 02:20:45
【问题描述】:

我正在研究多态性。我无法确定 Java 中关于这两个特性的类比。

假设Animal 类是一个具体的超类,CatDog 作为其子类。我知道这是一个继承的例子。但是CatDog 类不是Animal 类的多态吗?

我非常了解 Java 中的接口。我不明白为什么使用接口而不是具体的类来解释多态性。可能创建接口的全部目的是创建多态,但我想知道为什么是接口而不是具体类?

【问题讨论】:

标签: java interface polymorphism


【解决方案1】:

Inheritance

class Animal{
  public void speak(){ System.out.println("Speaking something");}
}

class Person extends Animal{
 @Override
 public void speak(){ System.out.println("Hello..");}
}  

Polymorphism

Animal a  = new Person();
a.speak();// Hello

多态性的字典定义是指一个原则 生物体或物种可以有许多不同形式的生物学 或阶段。这个原则也可以应用于面向对象 编程和语言,如 Java 语言。 a的子类 类可以定义自己独特的行为,但共享一些 父类[..]的功能相同


为什么选择接口?

你知道需要做什么,但你想让实施者决定如何去做,你会让实施者强行实施这些东西

【讨论】:

  • 所以只有在将子类的对象分配给它的超类的引用时才使用多态性?
【解决方案2】:

接口使用一种类型的多态性,即方法覆盖。

接口通常被用作常用方法的契约。

【讨论】:

    【解决方案3】:

    我不知道接口是解释多态性的最佳方式。多态性是遗传的产物。从观察者的角度来看,这是在查看继承层次结构时发生的事情。每只动物都可能发出声音,但当观察者真正观察到动物发出声音时,猫会喵喵叫,狗会吠叫。小型犬吠叫,而大型犬吠叫。多态性是使这些属性基于它们在继承层次结构中的位置隐式显示的能力。

    接口是实现组合的一种方式。您可以将属性添加到其他相关或不相关对象可能具有或不具有的对象。这只狗是个流口水者。而猫是一个抓挠者。不一定属于动物继承层次结构的其他事物也可能具有这些流口水和/或抓挠属性。

    【讨论】:

    • 显然,并非所有的多态都具有相同的超类。对吗?
    • 接口是一种在具有不同超类的对象之间合并相似属性的技术。但通常“多态性”是指具有共享超类的对象。
    【解决方案4】:

    继承在 Java 中实现为超类或接口的方法/字段的简单扩展,分别使用 extendsimplements 关键字。无论哪种方式,您都可以在子类中访问超类的公共和受保护数据成员,而从外部对子类进行操作时,只能访问公共数据成员。

    以你的例子为例,你可以定义几个类:

    class Animal {
        private int location;
    
        public Animal() {
            location = 0;
        }
    
        public void move() {
            location += 10;
        }
    
        public int getLocation() {
            return location;
        }
    }
    
    class Dog extends Animal {
        @Override
        public void move() {
            setLocation(getLocation() + 5);
        }
     }
    
    /*
     * The @Override flag is optional, but I prefer to put it there
     * to ensure that I am actually overriding a method or implementing
     * a method from an interface.
     */
    
    class Cat extends Animal {
        @Override
        public void move() {
            setLocation(getLocation() + 15);
        }
    }
    

    所以DogCat 都扩展了Animal - 这是一种继承关系。

    多态是完全不同的东西。根据维基百科:

    多态性在工业中的主要用途(面向对象的编程理论)是属于不同类型的对象能够响应同名的方法、字段或属性调用,每个调用根据适当的特定类型行为。

    用简单的英语术语来说,这只是意味着采取相同的想法或行动,并根据其具体类型的对象以不同的方式实现它。在代码中:

    public static void main(String[] args) {
        Animal animalArray = {
            new Animal(),
            new Cat(),
            new Dog()
        };
    
        for (Animal a : animalArray) {
            a.move();
        }
    
        System.out.println("Animal location: " + animalArray[0].getLocation());
        System.out.println("Cat location: " + animalArray[1].getLocation());
        System.out.println("Dog location: " + animalArray[2].getLocation));
    }
    

    这会产生输出:

    Animal location: 10
    Cat location: 15
    Dog location: 5
    

    请注意,每个对象,AnimalCatDog 都作为 Animals 访问。这是可能的,因为每个类都是或扩展Animal,因此每个类都将始终拥有公共方法move(),在某些情况下它只是被重新定义。

    接口的工作原理相同;如果一个类扩展了一个接口,则可以保证接口中定义的每个方法都有一些实现,因此可以根据接口实现的方法来使用它。

    【讨论】:

      【解决方案5】:

      假设您已被雇用来创建一种编程语言,这是要求之一:

      1 > 3 should call code from the integer comparison library.
      1.0 > 3.0 should call code from the floating point comparison library.
      "McDonald" > "MacDonald" should call code from the locale-aware string comparison library.
      

      该要求是“多态性”,其中相同的文本(> 运算符)根据情况(在本例中为操作数的类型)执行不同的操作。

      您可以通过将整数、浮点数和字符串全部派生自同一个基类并将基类定义为具有虚拟比较运算符来满足这些要求。这可能会变得混乱。如果稍后,语言用户想要...

      blue > yellow
      

      ...要编译为执行颜色操作的代码,基类方法意味着说颜色、字符串、浮点数和整数都是更通用基础的特殊情况。我觉得那会很奇怪。

      另一种方法是为应用程序开发人员提供一种语言方式来创建任意类型并说明它们支持哪些操作,并让库开发人员为支持一组操作的任何类型提供函数。例如,您可以为任何支持比较和赋值运算符的类型编写排序例程。

      这种方法称为接口,它的优点是可以很好地处理非常不同的类型。

      【讨论】:

        猜你喜欢
        • 2022-09-27
        • 2016-08-16
        • 2013-09-19
        • 2015-01-19
        • 2013-06-13
        • 2011-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多