这是多态吗?

时间:2012-05-21 22:28:55

标签: java polymorphism

我最近在采访中,在那次采访中,我意识到我的编程概念并没有我想象的那么具体。

我被问到,描述你以前工作中使用多态的时间?

经过一番思考后,我说我们有一个记录类,每个新记录都会扩展。因此,如果我们有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 个答案:

答案 0 :(得分:2)

长答案:是的 根据韦伯斯特的观点,多态性是:a(1):存在一种独立于性别变异的形式的物种(2):存在几种等位基因形式的基因(3):分子的存在(作为酶)单一物种中的几种形式b:具有不同结构的两种或多种形式的结晶性质

我们专注于定义a。在java术语中,这描述了使用1“top”类来引用两个“底部”类。据我所知,上面的例子显示了这一点。

答案 1 :(得分: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上调用它们,但是在每个对象上调用的实际方法是对象拥有该方法的实现。

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

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

所以简而言之。网上有大量的例子可以看一看。这是一个很棒的概念,非常值得花一些时间来理解。

答案 2 :(得分:0)

这个例子不适合解释多态性。

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

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

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

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

答案 3 :(得分: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!
        }
    }
}