我最近在采访中,在那次采访中,我意识到我的编程概念并没有我想象的那么具体。
我被问到,描述你以前工作中使用多态的时间?
经过一番思考后,我说我们有一个记录类,每个新记录都会扩展。因此,如果我们有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);
}
}
}
我只是缺少它,所以请不要挑选它。
我告诉他们这是使用多态,因为无论记录类型如何,都可以在不知道它是什么类型的记录的情况下编写。这很有价值,因为我们正在编写需要正确填充的文件,零填充或填充空格等...
如果这不是多态,请告诉我如何将我的示例更改为使用多态的内容。
答案 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!
}
}
}