1

我最近参加了一次采访,在那次采访中我意识到我的编程概念并不像我想象的那么具体。

有人问我,描述一下您在以前的工作中使用多态性的时间吗?

经过一番思考,我说我们有一个记录类,每条新记录都会扩展。因此,如果我们有 AddRecord 或 RemoveRecord 或任何其他类型的记录,它们将扩展 Record。记录界面看起来像这样:

public abstract Record{
  public writeLine(String line);
  public getColumn(int column);
  public setHeader(String header);
  ...
}

public AddRecord extends Record{
  public writeLine(String line){
      // do something
  }

  // etc...
}

public MakeRecord{
   Record r;
   public setRecord(Object s){
      if(s instanceof Record){
          r = s;
      }
   } 

   public void printNewRecord(){
      while(thingsToWrite){
          r.writeLine(something);
      }
   }
}

我只是简写了它,所以请不要挑它。

我告诉他们这是使用多态性,因为无论记录类型如何,都可以在不知道它是什么类型的记录的情况下编写它。这很有价值,因为我们正在编写需要正确填充的文件,无论是零填充还是用空格填充等......

如果这不是多态性,请告诉我如何将我的示例更改为使用多态性的东西。

4

4 回答 4

2

长答案简短:是的,根据韦伯斯特的说法,多态性是:a (1):物种以多种形式存在,与性别的变化无关 (2):基因以多种等位基因形式存在 (3):分子的存在(作为一种酶)在一个物种中以多种形式存在 b :以两种或多种具有不同结构的形式结晶的特性

我们专注于定义a。这在 Java 术语中描述为使用 1 个“顶级”类来引用两个“底部”类。据我所知,如上例所示。

于 2012-05-21T22:35:12.293 回答
1

一个非常基本的多态性示例:

import java.util.ArrayList;

public class TestClass{
  public static void main(String args[]) {
     ArrayList animals = new ArrayList();
     animals.add(new Bear());
     animals.add(new Fish());
     animals.add(new Animal());
     for (Animal a : animals){
         a.someMethod();
     }
  }
}

class Animal {
   public void someMethod(){
      System.out.println("I am an Animal");
   }
}

class Bear extends Animal{
   public void someMethod(){
      System.out.println("I am a Bear");
   }
}

class Fish extends Animal{
   public void someMethod(){
      System.out.println("I am a Fish");
   }
}

这个的输出是:

I am a Bear
I am a Fish
I am an Animal

所以我们可以在这里看到,调用每种类型对象的方法的循环都调用了 Animal 上的所有方法,而在每个对象上调用的实际方法是对象自己实现该方法。

显然,要使集合中的每个对象都可以工作,该方法必须具有此方法的实现,尽管如果适用于该对象,它显然可以使用超类的版本。

这意味着集合中的对象(作为如何使用它的示例)可以在运行时决定,并且不必单独类型转换回它们的真实形式,而可以简单地由父类调用类型或接口类型。这为代码提供了更大的灵活性,并使其更易于维护。它还允许更通用和松耦合的代码。

简而言之,就是这样。网上有很多例子可以看。这是一个绝妙的概念,非常值得花一些时间来理解。

于 2012-11-28T09:50:28.037 回答
0

该示例不利于解释多态性。

Addrecord 不是 Record 类的良好扩展。Addrecord 应该是方法而不是类。

所以基本上你应该有具有 Addrecord 方法的 Record 类,并且这个方法可以被特殊记录覆盖,比如 - ColumnnameRecord

如果您有从 Record 类派生的 specialRecord 类,并且 Record Class 具有被派生类覆盖的方法,那么您就有了很好的多态性示例。

当前示例在技术上是正确的,但在概念上并不正确。

于 2012-05-22T14:55:10.650 回答
0

多态性的另一个例子:

abstract class PolyGeometricEntity
{
    public int center_x__mm;                    // commen superset
    public int center_y__mm;                    // commen superset
    public void move(int d_x__mm, int d_y_mm)   // commen superset
    {
        center_x__mm += d_x__mm;
        center_y__mm += d_y_mm:
    }

    public abstract int area();                 // commen superset on abstract level, but specialized at implementation level
    public abstract void draw();               // commen superset on abstract level, but specialized at implementation level
}

class CircleEntity : PolyGeometricEntity
{
    public override int area()
    {
        // circle specific
        return 1;
    }
    public override void draw()
    {
        // draw a circle
    }
}

class TriangleEntity : PolyGeometricEntity
{
    public override int area()
    {
        // triangle specific
        return 1;
    }
    public override void draw()
    {
        // draw a triangle
    }
}


class PolyCanvas
{
    List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();

    void CreateEntity(string toCreateClass)
    {
        // assume that code is called by the ui
        // you do not know what the user decides at runtime
        // Polymorphism 'starting' now:
        PolyGeometricEntity toCreate = null;
        if (toCreateClass == "c") { toCreate = new CircleEntity(); }
        else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
        entities.Add(toCreate);
    }

    void ReDraw()
    {
        foreach (PolyGeometricEntity toDraw in entities)
        {
            toDraw.draw(); // polymorphism in action!
        }
    }
}
于 2016-05-10T16:05:26.953 回答