【问题标题】:Overloading methods using derived class objects referenced by base class - java使用基类引用的派生类对象重载方法 - java
【发布时间】:2011-09-15 17:25:57
【问题描述】:
class base{}

class childA extends base{}

class childB extends base{}

我有两个函数(重载) 像这样:

function(childA,childA){}

function(childA,childB){}

//主程序

base a = new childA();
base b = new childB();

function(a,b);   
function(a,a);  //problem

函数调用显然不会编译。

但是有没有一种方法可以在不使代码过于复杂或每次调用函数时进行类型检查的情况下获得相同的效果。

注意:重载函数独立于类。类只是数据结构,我宁愿没有任何相互依赖的代码。

附言。我经历了很多涉及类似问题的主题,但它们似乎并没有解决上述问题。对不起,如果我错过了什么,(新手,第一篇文章等:))。

编辑:

似乎我的例子有点含糊,我只是想从总体上理解这个概念,而不仅仅是解决眼前的问题。上面的代码不起作用似乎很奇怪,如果它起作用了,那将是一个强大的功能。

好吧,另一个例子,这几乎就是我想要做的。

class Shape{}

class Rectangle extends Shape{
//rectangle data
}

class Circle extends Shape{
//circle data
}

重载函数(另一个类的成员)

boolean checkIntersection(Rectangle r, Circle c){}
boolean checkIntersection(Circle c, Circle c){}

//主程序

Vector<Shape> shapes = new Vector<Shape>();
shapes.add(new Rectangle());
shapes.add(new Circle());
shapes.add(new Circle());

checkIntersection(shapes.get(0),shapes.get(1));
checkIntersection(shapes.get(1),shapes.get(2));

【问题讨论】:

  • 另外,Java标准是在命名类时使用UpperCamelCase。
  • 知道..但它并没有真正成为第二天性。我只在认真编写代码时使用它。

标签: java polymorphism overloading


【解决方案1】:

问题是您的方法将childAchildB 对象作为参数,而您却给它一个base 对象

更改方法签名以将基类作为参数,这样可以解决问题,但您会失去多态性

function(base a,base b){}

您可以做的是将变量 ab 更改为

childA a = new childA();
childB b = new childB();

如果你想坚持使用 base 而不是 childA 或 childB,也许你应该看看方法覆盖而不是重载。

你在 base 中定义一个方法

someMethod(){
  //do something
}

然后在你的子类中覆盖它

@override
someMethod(){
  //do something specific to childA
}

那么当你这样做时

base a = new childA();

然后打电话

a.doSomething();

它会调用childA中被覆盖的方法

【讨论】:

  • 你写了两次有什么原因吗?
  • 这不会破坏重载的目的吗?关于共享界面,您能详细说明一下吗?
  • 对不起,删除了我的帖子,因为我的回答完全错误,现在应该更好
  • 重载主要在Java中用于考虑可选参数(根据我的经验)。这通常会导致创建所谓的辅助方法。
  • 使用通用 function(Base arg0, Base arg1) 时会遇到的问题是,如果您想使用子类功能,您现在可以管理向下转换对象。
【解决方案2】:

以下内容对我有用:

class user9
{
    static class base
    {
    }

    static class childA extends base
    {
    }

    static class childB extends base
    {
    }

    static void function ( childA a , childB b )
    {
    }

    static void function ( childA a1  , childA a2 )
    {
    }

    public static void main ( String [ ] args )
    {
        childA a = new childA ( ) ;
        childB b = new childB (  ) ;
        function ( a , b ) ;
        function ( a , a ) ;
    }
}

【讨论】:

    【解决方案3】:
    abstract class Base{};
    
    class ChildA extends Base{};
    class ChildB extends Base{};
    
    public class JavaTest {
    
        public static void function( ChildA a, ChildA a2 ) {
            //do something
        }
    
        public static void function( ChildA a, ChildB b ) {
            //do something else
        }
    
        public static void function( Base a, Base a2 ) {
            //do something
        }
    
        public static void main(String[] args) {
            function( new ChildA(), new ChildA() );
            function( new ChildA(), new ChildB() );
            function( new ChildB(), new ChildA() ); //Uses function(Base, Base)
        }
    }
    

    这是使用您指定的 2 个重载的示例代码,以及 @Ben 建议的泛型重载。正如我在评论中提到的,如果您想使用特定的 ChildA/B 函数,则必须在使用泛型重载时放弃。

    【讨论】:

    • 谢谢,这就是我目前实现它的方式。我想知道的是,如果有办法让编译器在不明确检查类型和向下转换的情况下弄清楚它,似乎是不可能的:(
    【解决方案4】:

    您可能对Visitor pattern 感兴趣。

    【讨论】:

    • 谢谢,但不确定这正是我想要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    相关资源
    最近更新 更多