从单个对象继承的不同类型的集合与单个超级对象的集合

发布于 2024-09-27 07:29:30 字数 1436 浏览 4 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肥爪爪 2024-10-04 07:29:30

当我们掌握一般信息而不是具体事实时,很难给出解决方案。举个例子,xyz() 和 abc() 方法。它们是什么,为什么?在您的示例中,它们似乎具有类似的用途,因此我考虑在 Shape 中定义一个名为 doSomethingSpecific() 的抽象方法,以便所有 Shape 子类都可以实现它。
现在您的代码是:

   void drawAll()  
       {  
       for (Shape s : heterogeneousCollection)  
           {
           s.draw();                // common function present in Shape also  
           s.doSomethingSpecific(); //  specific to each implementation  
           }   
       }  

如果可能的话,我更喜欢异构集合。我非常不喜欢 instanceof ,原因正是您指出的 - 当我们将 Triangle 添加到混合中时会发生什么。

It's difficult to give solutions when we have general information instead of specific facts. Case in point, the xyz() and abc() methods. What are they, and why? In your example, they seem to have a similar use, so I'd consider defining an abstract method in Shape called doSomethingSpecific() so it would be implemented by all Shape subclasses.
Now your code is:

   void drawAll()  
       {  
       for (Shape s : heterogeneousCollection)  
           {
           s.draw();                // common function present in Shape also  
           s.doSomethingSpecific(); //  specific to each implementation  
           }   
       }  

I prefer heterogeneous collections when possible. I very much dislike instanceof for the very reason you point out - what happens when we add Triangle to the mix.

婴鹅 2024-10-04 07:29:30

假设有很多地方您确实需要独立处理圆形和方形,我将通过应用 访客模式

这样做的好处是,如果您稍后添加 Triangle,那么当您添加方法时
T VisitTriangle(Triangle triangle); 对于访问者来说,在更新每个访问者之前,您的代码不会编译,从而避免令人讨厌的运行时意外。

但是...如果您实际上只是在谈论以不同方式处理 Circle 和 Square 的单个实例,那么在这里应用 Visitor 就有点矫枉过正了,我只会考虑为 doSomeSpecificUiThing() 为 Shape 添加一个抽象方法。

它看起来像这样:

class ShapeVisitor<T>
{
    T visitCircle(Circle circle);
    T visitSquare(Square square);
}

class Shape
{
    abstract <T> T accept(ShapeVisitor<T> visitor);

    // methods of Class Shape
}

class Circle extends Shape
{
   <T> T accept(ShapeVisitor<T> visitor) {
       return visitor.visitCircle(this);
   }

   // methods of Class Circle 
}

class Square extends Shape
{
   <T> T accept(ShapeVisitor<T> visitor) {
       return visitor.visitSquare(this);
   }

  // methods of Class Square 
}

Class Canvas  
{  
    void drawAll()  
    {  
        for (Shape s : heterogeneousCollection)  
        {  
            s.draw();
            s.accept(new ShapeVisitor<Void>() {
                @Override Void visitCircle(Circle circle) {
                    circle.xyz();
                    return null;
                }

                @Override Void visitSquare(Square square) {
                    square.abc();
                    return null;
                }
            }
        }   
    }  
}  

Assuming that there are a number of places where you legitimately need to deal with processing Circle and Square independently, I would deal with the heterogeneous collection by applying the Visitor Pattern

This has the benefit that if you add Triangle later, then when you add a method
T visitTriangle(Triangle triangle); to the visitor, your code won't compile until you update every single visitor, avoiding nasty runtime surprises.

However... if you're really only talking about a single instance of processing Circle and Square differently, then applying Visitor here is overkill and I would just consider adding an abstract method to Shape for doSomeSpecificUiThing().

It would look something like this:

class ShapeVisitor<T>
{
    T visitCircle(Circle circle);
    T visitSquare(Square square);
}

class Shape
{
    abstract <T> T accept(ShapeVisitor<T> visitor);

    // methods of Class Shape
}

class Circle extends Shape
{
   <T> T accept(ShapeVisitor<T> visitor) {
       return visitor.visitCircle(this);
   }

   // methods of Class Circle 
}

class Square extends Shape
{
   <T> T accept(ShapeVisitor<T> visitor) {
       return visitor.visitSquare(this);
   }

  // methods of Class Square 
}

Class Canvas  
{  
    void drawAll()  
    {  
        for (Shape s : heterogeneousCollection)  
        {  
            s.draw();
            s.accept(new ShapeVisitor<Void>() {
                @Override Void visitCircle(Circle circle) {
                    circle.xyz();
                    return null;
                }

                @Override Void visitSquare(Square square) {
                    square.abc();
                    return null;
                }
            }
        }   
    }  
}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文