Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.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
Java 这是多态性吗?_Java_Polymorphism - Fatal编程技术网

Java 这是多态性吗?

Java 这是多态性吗?,java,polymorphism,Java,Polymorphism,我最近参加了一次采访,在采访中我意识到我的编程概念没有我想象的那么具体 有人问我,描述一下你以前工作中使用多态性的一段时间 经过一些思考,我说我们有一个记录类,每一个新的记录扩展。所以,如果我们有一个AddRecord或RemoveRecord或任何其他类型的记录,它们会扩展这个记录。记录界面如下所示: public abstract Record{ public writeLine(String line); public getColumn(int column); public

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

有人问我,描述一下你以前工作中使用多态性的一段时间

经过一些思考,我说我们有一个记录类,每一个新的记录扩展。所以,如果我们有一个AddRecord或RemoveRecord或任何其他类型的记录,它们会扩展这个记录。记录界面如下所示:

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”类来引用两个“bottom”类。就我所知,上面的例子显示了这一点。

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

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

所以基本上,您应该让Record类具有Addrecord方法,并且该方法可以被特殊记录(如-ColumnnameRecord)覆盖

如果您有从记录类派生的specialRecord类,并且记录类有被派生类重写的方法,那么您就有了多态性的好例子


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

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

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");
   }
}
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!
        }
    }
}
其输出为:

I am a Bear
I am a Fish
I am an Animal
因此,我们可以看到,在每种类型的对象上调用方法的循环都在Animal上调用它们,而在每个对象上调用的实际方法是对象拥有该方法的实现

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

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


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

多态性的另一个例子:

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");
   }
}
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!
        }
    }
}
抽象类polygeometricientity
{
public int center\u x\u mm;//公共超集
public int center\u y\u mm;//公共超集
公共无效移动(int d_x___mm,int d_y_mm)//公共超集
{
中心×毫米+=d×毫米;
中心直径+=d直径:
}
public abstract int area();//在抽象级别上是common超集,但在实现级别上是专用的
public abstract void draw();//在抽象级别上是commo超集,但在实现级别上是专用的
}
类循环实体:多几何实体
{
公共覆盖int区域()
{
//圈特定
返回1;
}
公共覆盖无效绘图()
{
//画圈
}
}
类三角形实体:多边形几何实体
{
公共覆盖int区域()
{
//三角形特定
返回1;
}
公共覆盖无效绘图()
{
//画一个三角形
}
}
保利坎瓦级
{
列表实体=新列表();
void CreateEntity(字符串toCreateClass)
{
//假设代码由ui调用
//您不知道用户在运行时决定了什么
//多态性“正在启动”:
PolyGeometriceEntity toCreate=null;
如果(toCreateClass==“c”){toCreate=new CircleEntity();}
else if(toCreateClass==“t”){toCreate=new TriangleEntity();}
实体。添加(创建);
}
作废重画()
{
foreach(实体中绘制的多边形几何实体)
{
toDraw.draw();//多态性正在运行!
}
}
}

面试官有没有告诉你那不是多态性?(如果答案是“是”,继续下一次面试,不要回头看。)在我看来不错,也许你的想法实际上比你想象的要好。有时候面试官会玩一些愚蠢的心理游戏来测试你的信念水平。提前回顾这些东西不会有什么坏处。(好吧,除了
instanceof
check.。那是干什么的?)好的,谢谢大家。我认为他在装傻,但感觉他不相信我,但这是通过电话:)一个更好的选择是使用方法
setRecord(Record s)
,如果传递错误的内容,则会出现编译错误(这是您想要的)。按照现在的代码方式,您将不会遇到编译错误、运行时错误,并且您的代码可能不会执行您想要的操作。这里真的需要生物学定义吗?在OOP上下文中提供了多态性的良好定义。我没有询问,而是将其设置为社区wiki,这是有原因的。如果你认为这会有助于更好地用不同的方式表达,那么就去做吧。