簡體   English   中英

這是多態嗎?

[英]Is this 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);
      }
   }
}

我只是缺少它,所以請不要隨意挑選它。

我告訴他們這是使用多態,因為無論記錄類型如何,都可以在不知道它是什么類型的記錄的情況下編寫。 這很有價值,因為我們正在編寫需要正確填充的文件,無論是零填充還是填充空格等...

如果這不是多態,請告訴我如何將我的示例更改為使用多態的內容。

答案簡短:是多態性,根據韋伯斯特:a(1):存在一種獨立於性別變異的形式的物種(2):存在幾種等位基因形式的基因(3):分子的存在(作為酶)在單一物種b中以幾種形式存在:具有不同結構的兩種或更多種形式的結晶性質

我們專注於定義a。 在java術語中,這描述了使用1“top”類來引用兩個“底部”類。 據我所知,這在上面的例子中顯示。

多態的一個非常基本的例子:

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上調用它們,然而在每個對象上調用的實際方法是對象擁有該方法的實現。

很明顯,為了實現這一點,集合中的每個對象都必須具有此方法的實現,盡管如果它適合該對象,它顯然可以使用超類的版本。

這意味着集合中的對象(作為如何使用它的一個示例)可以在運行時決定,並且不必單獨類型轉換回其真實形式,但可以簡單地由父類調用類型或接口類型。 這允許代碼具有更大的靈活性,並使其更易於維護。 它還允許更通用和松散耦合的代碼。

所以簡而言之。 網上有大量的例子可以看一看。 這是一個很棒的概念,值得花一些時間來理解。

這個例子不適合解釋多態性。

Addrecord不是Record類的良好擴展。 Addrecord應該是方法而不是類。

所以基本上你應該讓Record類具有Addrecord方法,並且這個方法可以被特殊記錄覆蓋,例如 - ColumnnameRecord

如果您有從Record類派生的specialRecord類,而Record類具有被派生類覆蓋的方法,那么您就擁有了很好的多態性示例。

當前示例在技術上是正確的,但在概念上不正確。

多態性的另一個例子:

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!
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM