如何在UML中建模多态性和实例?

4

我发现在UML中对多态和实例进行建模很困难。

例如,如果我有一个称为“Bird”的抽象、父或基类,我会想象“duck”是多态的一种形式,但它也可以是一个实例。

也许我混淆了开始和结束的位置。是否有这些的视觉示例呢?


1
http://usna86-techbits.blogspot.com/2012/11/uml-class-diagram-relationships.html - Babak Naffas
2
可以给我的问题投反对票,但如果你不告诉我为什么,我就不知道原因,也许无法纠正我的问题。 - PeanutsMonkey
1
一个类图并不能捕捉实例。一只鸭子可能是 - 就是 - 一种鸟的类型,而麦克夫先生可能是一只特定的鸭子。当然,根据范围/任务,人们可以选择将鸭子建模为单独的关系 - 基本上,一小组有限原型可以被建模为类,而无限集合的数据只能由所述关系的"实例"表示。 - user2864740
@user2864740 类图没有实例元素,但是可以间接地谈论它们 - 抽象类或接口没有实例,具体类则有。 - Gangnus
3个回答

3
继承与实例的问题取决于功能。如果你的数据模型在鸭子和其他类型的鸟之间有任何差异,那么你会想要一个从鸟类继承的Duck类。否则,你只是将你的鸭子看作Bird的一个实例。
多态性仅在您跨不同的Bird实现调用相同的方法时发挥作用。
对于UML建模,以下是一些帮助你的要点。
这本书是许多软件工程课程的必读书籍,多年来一直为我服务。

http://www.amazon.com/UML-Distilled-Standard-Modeling-Language/dp/0321193687

这篇博客很好地展示了不同的用例和相应的面向对象编程模型。http://usna86-techbits.blogspot.com/2012/11/uml-class-diagram-relationships.html

谢谢Babak。你能在你提到的继承和实例的例子中给出多态性的例子吗? - PeanutsMonkey

3

这很简单。

如果一个具体的类Cage引用了抽象类Bird,并且具体的类Woodpecker和Canary都继承自Bird,那么这就是多态性。你必须选择真正会坐在笼子里的鸟,因为抽象类没有实例。接口也是同理。

enter image description here


抱歉,我不太明白。你的意思是Canary不是Bird的实例,而是代表多态性。那么它什么时候是一个实例呢?我的理解是Canary将是一个实例,而它的行为(例如声音)将是多态性。 - PeanutsMonkey
1
@PeanutsMonkey Canary不是任何实例,它是一个类。这里没有任何实例。你只看到可以或不可以有实例的类。Canary派生自抽象类Bird。而Canary类可以有实例——那些小黄色的唱歌动物。 - Gangnus
谢谢Gangnus。那么这就是泛化或特化。这如何与实例和多态性相对应? - PeanutsMonkey
1
@PeanutsMonkey 鸟不能有实例,但是笼子有鸟,所以必须用金丝雀或啄木鸟替换才能获得实例。这就是多态性。 - Gangnus
@PeanutsMonkey 所以,你有一个名为 Cage 的类,其内容可以是 Canary XOR Woodpecker。 - Gangnus

1

首先,我认为你的问题是如何建模多态性。为了说明这一点,看下面的Java代码:

Drawable.java

package examples.simple.model;

public interface Drawable {
    public void draw();
}

Shape.java

package examples.simple.model;

public abstract class Shape  implements Drawable {
    private Point center;

    public Point getCenter() {
        return center;
    }

    public void setCenter(Point center) {
        this.center = center;
    }
}

Rectangle.java

package examples.simple.model;

public class Rectangle extends Shape {
    public void draw() {
        System.out.println("Drawing a rectangle....");
    }
}

Circle.java

package examples.simple.model;

public class Circle extends Shape {
    public void draw() {
        System.out.println("Drawing a circle....");
    }
}

Line.java

package examples.simple.model;

public class Line implements Drawable{
    public void draw() {
        System.out.println("Drawing a line");
    }
}

Plotter.java

package examples.simple.client;

import java.util.ArrayList;
import java.util.List;

import examples.simple.model.Circle;
import examples.simple.model.Drawable;
import examples.simple.model.Rectangle;
import examples.simple.model.Shape;
import examples.simple.model.Line;

class Plotter {

    public static void main(String[] args) {
        List<Drawable> drawables = new ArrayList<Drawable>();

        Shape s = new Circle();
        drawables.add(s);

        s = new Rectangle();
        drawables.add(s);

        Line l = new Line();
        drawables.add(l);

        for (Drawable drawable : drawables) {
            drawable.draw();
        }
    }
}

这是多态的经典示例。类图如下:

enter image description here

在这种情况下,使用序列图,通过由守卫条件控制的多个场景来建模多态调用。因此,对于每个多态场景,动态绑定(多态调用)都表示为一个“场景框”。因此,这是一个单一的模型(序列图),用于显示多态调用。

Sequence Diagram to represent polymorphic scenarios

最后,使用UML表示多态调用实际上是一项挑战。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接