Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 多态性如何使我的代码更灵活?_Oop_Polymorphism - Fatal编程技术网

Oop 多态性如何使我的代码更灵活?

Oop 多态性如何使我的代码更灵活?,oop,polymorphism,Oop,Polymorphism,我正在阅读Head First面向对象设计,以便更好地理解OOP概念 多态性解释为: Airplane plane = new Airplane(); Airplane plane = new Jet(); Airplane plane = new Rocket(); 您可以编写在超类(如飞机)上工作的代码,但可以与任何子类一起工作。:-*嗯我得到了这个。* 它进一步解释说: ->那么多态性如何使代码灵活呢? 如果需要新功能,可以编写 飞机。但是,由于您的代码使用了超类,因此新类可以正常工作

我正在阅读Head First面向对象设计,以便更好地理解OOP概念

多态性解释为:

Airplane plane = new Airplane();
Airplane plane = new Jet();
Airplane plane = new Rocket();
您可以编写在超类(如飞机)上工作的代码,但可以与任何子类一起工作。:-*嗯我得到了这个。*

它进一步解释说:

->那么多态性如何使代码灵活呢?

如果需要新功能,可以编写 飞机。但是,由于您的代码使用了超类,因此新类可以正常工作 不需要对代码的其余部分进行任何更改

现在我不明白了。我需要创建一个飞机的子类。例如:我创建了一个类,
Randomflyer
。要使用它,我必须创建它的对象。因此,我将使用:

Airplane plane = new Randomflyer();

我不明白。甚至我也会直接创建子类的对象。当我添加一个新的子类时,我仍然认为没有必要在任何地方更改代码。使用超类如何避免我对代码的其余部分进行额外更改?

假设您有以下(简化的):

然后你用它做各种各样的事情:

List<Airplane> formation = ...
// superclass is important especially if working with collections
formation.add(plane);
// ...
plane.flyStraight();
plane.crashTest();
// ... insert some other thousand lines of code that use plane
我在上面写的所有其他代码都可以正常工作(当然不同),因为其他代码依赖于general
Planet
类提供的接口(读:public methods),而不是一开始提供的实际实现。通过这种方式,您可以在不更改其他代码的情况下传递不同的实现

如果您没有使用
飞机
超类,只是编写了
myframe
pterdoactylsuperjet
,以替换

MyAriplane plane = new MyAirplane();

那么你就有一个要点:剩下的代码可能仍然可以工作。但这恰好是可行的,因为您故意在两个类中编写了相同的接口(公共方法)。如果您(或其他开发人员)更改某个类中的接口,在飞机类之间来回移动将导致代码无法使用

编辑

我所说的故意,是指您在
myplanet
PterodactylSuperJet
中具体实现了具有相同签名的方法,以便您的代码能够在这两者中正确运行。如果您或其他人更改了一个类的接口,那么您的灵活性就被破坏了

例如。假设你没有
飞机
超类,另一个毫无戒心的开发人员修改了这个方法

public void flyStraight()
在我的飞机中

public void flyStraight (int speed)
并假设您的
plane
变量的类型为
myplanet
。然后大代码将需要一些修改;假设这是需要的。问题是,如果您返回到
翼手龙超级喷气机
(例如,为了测试它,比较它,有太多的原因),您的代码将无法运行。为什么。因为您需要提供
PterodactylSuperJet
方法
flytright(int-speed)
您没有编写。你可以这样做,你可以修理,没关系

这是一个简单的场景。但是如果

  • 这个问题在无辜的修改一年后就折磨着你了?你甚至可能忘了当初为什么这么做
  • 一个也没有,但是发生了大量你无法跟踪的修改?即使你能跟上进度,你也需要让新课程跟上进度。几乎从来都不容易,也绝对不会令人愉快
  • 你有一百架飞机而不是两架飞机
  • 上述任何线性(或非线性)组合
如果您编写了一个
飞机
超类,并使每个子类覆盖其相关方法,那么通过在
飞机
中将
flytright()
更改为
flytright(int)
,您将被迫相应地调整所有子类,从而保持一致性。因此,灵活性不会改变

结束编辑


这就是为什么超类仍然是某种“爸爸”,因为如果有人修改它的接口,所有的子类都会跟着修改,因此你的代码会更灵活。

假设你的控制器类中有像这样的方法

parkPlane(Airplane plane)

在您的程序中实现。它不会破坏您的代码。 我的意思是,只要它接受参数为
飞机
,它就不需要改变

因为它可以接受任何类型的飞机,
flyer
highflyr
战斗机
,等等

此外,在集合中:

列表平面//将占用您的所有飞机

下面的示例将明确您的理解


现在你有一架战斗机来执行它,所以

public class Fighter implements Airplane {

    public void  parkPlane(){
        // Specific implementations for fighter plane to park
    }
    public void  servicePlane(){
        // Specific implementatoins for fighter plane to service.
    }
}
HighFlyer和其他类别也一样:

public class HighFlyer implements Airplane {

    public void  parkPlane(){
        // Specific implementations for HighFlyer plane to park
    }

    public void  servicePlane(){
        // specific implementatoins for HighFlyer plane to service.
    }
}
现在想想你的控制器类多次使用
飞机

假设您的控制器类是AirPort,如下所示

public Class AirPort{ 

AirPlane plane;

public AirPlane getAirPlane() {
    return airPlane;
}

public void setAirPlane(AirPlane airPlane) {
    this.airPlane = airPlane;
 }

}
这里的神奇之处在于,多态性使您的代码更加灵活,因为,

您可以根据需要创建新的
飞机
类型实例,并且不进行更改

机场的代码

您可以根据自己的喜好设置
AirPlane
实例(这也被称为依赖项)

现在想想,如果你创建了新类型的飞机,或者你移除了任何类型的飞机,这会对你的
机场产生影响吗


不,因为我们可以说
机场
类在多态性上指的是
飞机

据我所知,优势在于,例如,在飞机战斗游戏中,你必须在每个循环中更新所有飞机的位置,但你有几架不同的飞机。假设你有:

  • 米格-21
  • Waco 10
  • 三菱零
  • 日食500
  • 海市蜃楼
您不希望必须像这样单独更新它们的移动和位置:

Mig21 mig = new Mig21();
mig.move();
Waco waco = new Waco();
waco.move();
Mitsubishi mit = new Mitsubishi();
mit.move();
...
AirplaneFactory factory = new AirplaneFactory();

Airplane planeOne = factory.buildAirplane();
Airplane planeTwo = factory.buildJet();
Airplane planeThree = factory.buildRocket();
你想要一辆超级跑车吗
public class Fighter implements Airplane {

    public void  parkPlane(){
        // Specific implementations for fighter plane to park
    }
    public void  servicePlane(){
        // Specific implementatoins for fighter plane to service.
    }
}
public class HighFlyer implements Airplane {

    public void  parkPlane(){
        // Specific implementations for HighFlyer plane to park
    }

    public void  servicePlane(){
        // specific implementatoins for HighFlyer plane to service.
    }
}
public Class AirPort{ 

AirPlane plane;

public AirPlane getAirPlane() {
    return airPlane;
}

public void setAirPlane(AirPlane airPlane) {
    this.airPlane = airPlane;
 }

}
JumboJetPlane // implementing AirPlane interface.
AirBus        // implementing AirPlane interface.
Mig21 mig = new Mig21();
mig.move();
Waco waco = new Waco();
waco.move();
Mitsubishi mit = new Mitsubishi();
mit.move();
...
airplaneList.append(new Mig21());
airplaneList.append(new Waco());
airplaneList.append(new Mitsubishi());
...
for(Airplane airplane : airplanesList)
    airplane.move()
for(Animal a: animals) 
{
    a.makeNoise();
}
Animal animal = new Dog;
for (AirPlane p : airPlanes) {
    p.fly();
}
AirplaneFactory factory = new AirplaneFactory();

Airplane planeOne = factory.buildAirplane();
Airplane planeTwo = factory.buildJet();
Airplane planeThree = factory.buildRocket();
public Airplane buildDefault() {
    return new Jet();
}
public Airplane buildDefault() {
    return new Rocket();
}