[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends:00500] 型情報によるディスパッチ ( に似たもの) がメソッドオーバーロードで実現できない理由 ? (Re: Java プログラマーのための Perl 入門 ?)



えんどうです。

> >私が主題にしていたのは Java ではなく、
> >「クロージャーが存在する言語では"Javaのメソッドオーバーロード"相当の
> >ことが動的なディスパッチで可能である」と言いたかったわけです。
> 
> クロージャーと何の関係が?

他の言語は知りませんが、
Scheme では lambda があればオブジェクト指向システムが実現できます。

> Shape[] shapes;

やっと分かりました。

親の型の配列に入っているから「ディスパッチ」されない、
ということですね?

結局、個々の Shape サブクラス型オブジェクトに"型タグ"みたいなものを
付けておき、ディスパッチの仕組みを自前で書くしかないのですね。

> だめでないと思うなら、「こういうの」で上記の問題をどう書くか、
> 是非教えてください。具体的なコードで。

どういうツッコミが入るか想像がつきますが、とりあえず書きました。

public abstract class Shape {
    public abstract void paint();
}

public class Point extends Shape {
    private double x;
    private double y;
    
    public Point(double newX, double newY) {
        x = newX;
        y = newY;       
    }

    public double getX() {return x;}
    public double getY() {return y;}

    public void paint() {
        DisplayManager.draw(this);
    }
}

public class Line extends Shape {
    private double startX;
    private double startY;
    private double endX;
    private double endY;

    public Line(double newStartX, double newStartY, double newEndX, double newEndY) {
        startX = newStartX;
        startY = newStartY;
        endX = newEndX;
        endY = newEndY;     
    }
    
    public double getStartX() { return startX; }
    public double getStartY() { return startY; }
    public double getEndX() { return endX; }
    public double getEndY() { return endY; }
    
    public void paint() {
        DisplayManager.draw(this);
    }
}

public class Circle extends Shape {
    private double x;
    private double y;
    private double radius;

    public Circle(double newX, double newY, double newRadius) {
        x = newX;
        y = newY;
        radius = newRadius;
    }

    public double getX() { return x; }
    public double getY() { return y; }
    public double getRadius() { return radius; }
    
    public void paint() {
        DisplayManager.draw(this);
    }
}

public class DisplayManager {
    
    public static void draw(Shape s) {
        s.paint();
    }
    
    public static void draw(Point p) {
        double x = p.getX();
        double y = p.getY();
        System.out.println("drawPoint");
    }
    
    public static void draw(Line l) {
        double sx = l.getStartX();
        double sy = l.getStartY();
        double ex = l.getEndX();
        double ey = l.getEndY();
        System.out.println("drawLine");
    }
    
    public static void draw(Circle c) {
        double x = c.getX();
        double y = c.getY();
        double radius = c.getRadius();
        System.out.println("drawCircle");
    }
    
    public static void main(String[] args) {
        Shape[] list = new Shape[3];
        list[0] = new Point(10.0, 10.0);
        list[1] = new Line(0.0, 0.0, 20.0, 30.0);
        list[2] = new Circle(5.0, 5.0, 12.0);
        for (int i=0; i<list.length; i++) {
            draw(list[i]);
        }
    }

}

-- 
ENDO Yasuyuki <yasuyuki@xxxxxxxxxxxx>
http://www.javaopen.org/~yasuyuki/
http://www.javaopen.org/jfriends/