继承和多态之间的区别

时间:2012-06-11 02:20:45

标签: java interface polymorphism

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

假设Animal类是具有CatDog作为其子类的具体超类。我知道这是继承的情况。但不是CatDog类,Animal类的多态?

我很清楚Java中的接口。我无法理解为什么使用接口而不是具体类来解释多态性。可能是创建界面的整个目的是创建多态,但我想知道为什么接口而不是具体的类?

5 个答案:

答案 0 :(得分:6)

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的子类   class可以定义自己独特的行为并分享一些   父类[..]

的相同功能

为何选择界面?

你知道需要做什么,但是你希望实施者决定如何去做,你会让实施者强有力地实施这些东西

答案 1 :(得分:2)

Interface使用一种类型的多态,即Method overriding。

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

答案 2 :(得分:1)

我不知道接口是解释多态性的最佳方法。多态性是遗传的产物。这是从观察者的角度看待继承层次结构时发生的事情。每只动物都可以发出声音,但是当观察者实际上观察到动物发出声音时,猫喵喵叫着吠叫。当大狗叫喊时,小狗拉着嘴。多态性是使这些属性基于它们在继承层次结构中的位置隐式展示的能力。

接口是实现构图的一种方式。您可以向其他相关或不相关对象可能具有或不具有的对象添加属性。狗是一个流氓。虽然这只猫很划伤。其他不一定是动物继承层次结构的东西也可能具有这些流口水和/或刮擦属性。

答案 3 :(得分:1)

继承在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都会被Animal访问。这是可能的,因为每个类都是或扩展Animal,因此每个类将始终具有公共方法move(),在某些情况下只需重新定义。

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

答案 4 :(得分:0)

假装您已被聘用来创建编程语言,这是其中一项要求:

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

...要编译为执行颜色操作的代码,基类方法意味着颜色,字符串,浮点数和整数都是更一般基础的特殊情况。我认为这很奇怪。

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

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