Abstract method with variable list of arguments

前端 未结 5 1363
轮回少年
轮回少年 2021-02-05 07:09

I haven\'t quite found an elegant way to solve this issue. I have an abstract class that several other classes are inheriting with an abstract method that can contain anywhere f

5条回答
  •  野的像风
    2021-02-05 07:40

    I've struggled with the same question, and there's not a perfect answer, but I can give you a few things to consider. First, you're basically trying to do something that is inherently against Object Oriented Programming, which is that you're trying to create a variable interface. The point of an interface is that code that gets an abstract version of the object (the Item rather than the Book, for example), knows how to invoke the use() method. This means that they must know what can be passed to the use() method. If the answer depends on the implementation of the abstract class or interface, then you need to ensure that the code using it actually knows what kind of implementation (Book, etc.) that it's using, otherwise it's not going to know how to invoke use() with the appropriate parameters anyway. It sounds like you need to refactor your code, in all honesty.

    However, there is a way to answer your question as stated without refactoring the architecture. You could create a class that's data is all of the different types of parameters that could possibly be passed to the use() method, have the calling code set the fields of that class, and then pass that to the use() method. For example:

    public class UseParameters {
        private String string;
        private Queue queue;
        // Any other potential parameters to use(...)
    
        public void setString(String string) {
            this.string = string;
        }
    
        public String getString() {
            return string;
        }
    
        // All of the other accessor methods, etc.
    }
    

    Then, you could define the use method in Item like this:

    public abstract void use(UseParameters params);
    

    And any code using an Item would have to set the parameters of the object appropriately:

    Item item = // However you're going to get the item
    UseParameters params = new UseParameters();
    params.setString("good string");
    params.setQueue(new Queue());
    item.use(params);
    

    I just want to point out that if the code above knows the Item is a Book (which is how it knows to set the String and Queue, then why not just get a Book and skip needing an abstract class with a variable use() method altogether? But I digress. Anyway, the Book would then implement the use() method like so:

    @Override
    public void use(UseParameters params) {
        if(params.getString == null || params.getQueue() == null)
            // throw exception
    
        // Do what books do with strings and queues
    }
    

    I think that gets you what you want, but you should consider refactoring, I think.

提交回复
热议问题