Java 遗传和多态性之间的主要区别是什么?

Java 遗传和多态性之间的主要区别是什么?,java,oop,inheritance,polymorphism,Java,Oop,Inheritance,Polymorphism,今天,在模块期末开卷考试中,我发现自己迷路了。我正在阅读headfirstjava,两个定义似乎完全相同。我只是想知道我自己的想法的主要区别是什么。我知道有很多类似的问题,但我没有看到一个确切的答案。主要区别在于多态性是遗传的特定结果。多态性是根据对象的类型在运行时确定要调用的方法的地方。当一个类从另一个类继承并重写特定方法时,就会出现这种情况。但是,在普通的继承树中,您不必重写任何方法,因此并非所有方法调用都必须是多态的。这有意义吗?这是一个类似的问题,所有的福特汽车都是汽车,但并不是所有的汽

今天,在模块期末开卷考试中,我发现自己迷路了。我正在阅读
headfirstjava
,两个定义似乎完全相同。我只是想知道我自己的想法的主要区别是什么。我知道有很多类似的问题,但我没有看到一个确切的答案。

主要区别在于多态性是遗传的特定结果。多态性是根据对象的类型在运行时确定要调用的方法的地方。当一个类从另一个类继承并重写特定方法时,就会出现这种情况。但是,在普通的继承树中,您不必重写任何方法,因此并非所有方法调用都必须是多态的。这有意义吗?这是一个类似的问题,所有的福特汽车都是汽车,但并不是所有的汽车都是福特(虽然不是很……)


此外,多态性处理方法调用,而继承还描述数据成员等。

继承是指“类”从现有的“类”派生。因此,如果你有一个
Person
类,那么你有一个扩展
Person
Student
类,
Student
继承了
Person
所拥有的所有东西。关于您亲自在字段/方法上添加的访问修饰符,有一些细节,但这是基本思想。例如,如果在
Person
上有一个私有字段,
Student
将看不到它,因为它的私有字段对子类不可见

多态性处理程序如何决定它应该使用哪些方法,这取决于它所拥有的东西的类型。如果您有一个
Person
,它有一个
read
方法,您有一个
Student
扩展
Person
,它有自己的
read
实现,那么调用哪个方法是由运行时为您确定的,具体取决于您是有
Person
还是
Student
。这会变得有点棘手,但如果你像

Person p = new Student();
p.read();
调用了Student上的read方法。这就是多态性的作用。您可以执行该作业,因为
学生
,但运行时足够聪明,可以知道
p
的实际类型是学生


请注意,细节因语言而异。例如,您可以在javascript中执行继承,但它与在Java中的工作方式完全不同。

继承是指在子类中使用超类的结构和行为


多态性是指改变子类中超类的行为。

继承是指类a从其所有父类继承所有非静态受保护/公共方法/字段,直到对象。

多态性是一种表达具有相似特征的对象类型之间共同行为的方法。它还允许通过覆盖来创建这些特征的变化。继承是通过对象表示关系和抽象行为的对象层次结构实现多态性的一种方法。但这并不是实现多态性的唯一方法。原型是表达多态性的另一种不同于继承的方式。JavaScript是使用原型的语言的一个例子。我想还有其他方法。

继承更像是一个静态的东西(一个类扩展了另一个类),而多态性是一个动态/运行时的东西(对象根据其动态/运行时类型而不是静态/声明类型进行行为)

例如


->尽管a的静态/声明类型是a,但实际的动态/运行时类型是B,因此a.foo()将执行B中定义的foo,而不是a中定义的foo。多态性:以类似方式处理不同类型对象的能力。长颈鹿和鳄鱼都是动物,动物可以移动。如果您有一个
动物的实例
,那么您可以调用
移动
,而不需要知道或关心它是什么类型的动物


继承:这是同时实现多态性和代码重用的一种方法

其他形式的多态性: 还有其他实现多态性的方法,例如接口,它只提供多态性,而不提供代码重用(有时代码非常不同,例如蛇的
Move
,与狗的
Move
,在这种情况下,接口将是更好的多态选择


在其他动态语言中,多态性可以通过Duck类型实现,即类甚至不需要共享相同的基类或接口,它们只需要具有相同名称的方法。或者,更动态的是,像Javascript,您甚至不需要类,只需具有相同方法名称的对象就可以多态性地使用

在Java中,两者密切相关,这是因为Java使用了一种称为“动态分派”的方法调用技术

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A
然后我们看到B继承了A的
spin
。然而,当我们试图像操纵A型对象一样操纵对象时,我们仍然得到了B的
draw
行为。
draw
行为是多态的

在一些语言中,多态性和继承关系不是很密切。例如,在C++中,未声明虚函数是继承的,但不会动态调度,所以即使使用继承也不会得到多态行为。 在javascript中,每个函数调用都是动态调度的,您的类型很弱。这意味着您可能有一堆不相关的对象,每个对象都有自己的

draw
,让一个函数迭代它们并调用函数,每个对象都将
public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A
├── Animal
└── (instances)
    ├── Cat
    ├── Hamster
    ├── Lion
    └── Moose

├── interface-for-diet
│   ├── Carnivore
│   └── Herbivore
├── interface-for-habitat
│   ├── Pet
│   └── Wild

public class Animal {
    void breath() {
    };
}

public interface Carnivore {
    void loveMeat();
}

public interface Herbivore {
    void loveGreens();
}

public interface Pet {
    void liveInside();
}

public interface Wild {
    void liveOutside();
}

public class Hamster extends Animal implements Herbivore, Pet {

    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbor is a Gerbil");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
    }
}

public class Cat extends Animal implements Carnivore, Pet {
    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbr is a Gerbil");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Tuna, Chicken, and More");
    }
}

public class Moose extends Animal implements Herbivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat grass");
    }
}

public class Lion extends Animal implements Carnivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Moose");
    }
}
class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;
interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}