1 2 Previous Next 22 Replies Latest reply: Jun 23, 2012 12:02 AM by jschellSomeoneStoleMyAlias Go to original post RSS
      • 15. Re: extending classes which contains static methods
        Carlo A
        Sorry, i don't want to put any word mouth to anybody (nevertheless be offensive). From your answer it seems (to me, but tell me if i'm wrong) that my question is very strange to you but i don't see any strangeness. If it is true that my question is strange please help me understand why: it's more important for me to understand this than the original question.
        About the real problem it isn't very important (but it was for me a "matter of principle") and I thought it would be interesting for others too.
        It's quite difficult to extract from the whole project. In the example of my first post i tried to be as simple as possible, so i'm sorry if i don't explained the problem clearly.
        In the following code you can see something similar to the code i have (it isn't the code i written, but the code i have at the current time = the starting point).
        public class IODescriptionTest {
        
             public static void main(String[] args) {
                  InputOutput in = new DigitalInput("fc1");
                  InputOutput out = new DigitalOutput("y102");
        
                  /* here i need the description of some InputOutput objects */
                  System.out.println("in.description()=" + in.description());
                  System.out.println("out.description()=" + out.description());
        
                  /*
                   * here i need the description of a DigitalInput and a DigitalOutput without having a reference to the relative object
                   * and i cannot instantiate an object due to side effects.
                   */
                  System.out.println("\"fc2\" description=" + DigitalInput.description("fc2"));
                  System.out.println("\"k11\" description=" + DigitalOutput.description("k11"));
             }
        }
        
        class Translator {
             public static String translate(String key) {
                  return "translation of \"" + key + "\"";
             }
        }
        
        abstract class InputOutput {
             String name;
             public InputOutput(String name) { this.name = name; }
             public abstract String descriptionKey();
             public String description() { return Translator.translate(descriptionKey()); }
        }
        
        class DigitalInput extends InputOutput {
             public static final String prefix = "digital.input.";
             public DigitalInput(String name) { super(name); }
             public String descriptionKey() { return descriptionKey(name); }
             public static String description(String name) { return Translator.translate(descriptionKey(name)); }
             public static String descriptionKey(String name) { return prefix + name; }
        }
        
        class DigitalOutput extends InputOutput {
             public static final String prefix = "digital.output.";
             public DigitalOutput(String name) { super(name); }
             public String descriptionKey() { return descriptionKey(name); }
             public static String description(String name) { return Translator.translate(descriptionKey(name)); }
             public static String descriptionKey(String name) { return prefix + name; }
        }
        In the code above i don't like the followings:

        - The description() method of InputOutput class is logically identical to the description(String name) static method of every derived class. I think it would be preferable to have only one method.
        - descriptionKey(), description(String name) and descriptionKey(String name) methods are repeated identical in each classes that extends InputOutput class. I think it would be preferable to have only one method in the base class.


        Obviously in my real classes there're other things i removed for simplicity.

        As stated in the code remarks the need to have a static method to get the description is becouse i cannot create an instance due to others side effects.

        I hope i explained clearly enough the problem.

        Carlo

        Edited by: Carlo A on 22-giu-2012 2.38
        • 16. Re: extending classes which contains static methods
          darke
          public class IODescriptionTest  {
          
               public static void main(String[] args) {
                    InputOutput in = new DigitalInput("fc1");
                    InputOutput out = new DigitalOutput("y102");
          
                    /* here i need the description of some InputOutput objects */
                    System.out.println("in.description()=" + in.description());
                    System.out.println("out.description()=" + out.description());
          
                    /*
                     * here i need the description of a DigitalInput and a DigitalOutput
                     * without having a reference to the relative object and i cannot
                     * instantiate an object due to side effects.
                     */
                    System.out.println("\"fc2\" description="
                              + InputOutput.description("fc2", DigitalInput.class));
                    System.out.println("\"k11\" description="
                              + InputOutput.description("k11", DigitalOutput.class));
               }
          }
          
          class Translator {
               public static String translate(String key) {
                    return "translation of \"" + key + "\"";
               }
          }
          
          class InputOutput {
               
               public static String getPrefix(Class clazz) {
                    if (clazz.equals(DigitalInput.class)) {
                         return "digital.input";
                    }
                    if (clazz.equals(DigitalOutput.class)) {
                         return "digital.output";
                    }
                    throw new IllegalArgumentException("Unknown class");
               }
          
               String name;
          
               public InputOutput(String name) {
                    this.name = name;
               }
          
               public String description() {
                    return Translator.translate(getPrefix(this.getClass()) + name);
               }
          
               public static String description(String name, Class clazz) {
                    return Translator.translate(getPrefix(clazz) + name);
               }
          }
          
          class DigitalInput extends InputOutput {
               public DigitalInput(String name) {
                    super(name);
               }
          }
          
          class DigitalOutput extends InputOutput {
               public DigitalOutput(String name) {
                    super(name);
               }
          
          }
          • 17. Re: extending classes which contains static methods
            Carlo A
            Thanks for your answer, but I think it isn't a good OOP solution becouse if someone has to create its own InputOutput derived class he/she has to edit InputOutput base class.
            Also if another class is created extending DigitalInput or DigitalOutput classes the getPrefix(Class clazz) method doesn't work on objects of those classes.
            Keep in mind the code i presented is an extract of a complex/big project.

            Carlo
            • 18. Re: extending classes which contains static methods
              darke
              Carlo A wrote:
              Thanks for your answer, but I think it isn't a good OOP solution becouse if someone has to create its own InputOutput derived class he/she has to edit InputOutput base class.
              keep a map or external config
              Also if another class is created extending DigitalInput or DigitalOutput classes the getPrefix(Class clazz) method doesn't work on objects of those classes.
              Class#isAssignableFrom()
              Keep in mind the code i presented is an extract of a complex/big project.

              Carlo
              • 19. Re: extending classes which contains static methods
                800268
                You'll have to introduce a new interface/class which describes the InputOut so you can use it without an InputOutput instance (and can delegate the normal methods to).
                interface IODescriptor {
                  String getName();
                  String getDescription();
                  InputOutput createIO();
                }
                
                public abstract class AbstractIODescriptor implements IODescriptor {
                  // save name, prefix and implements getDescription() with translator
                }
                
                public abstract class InputOutput {
                  public InputOutput(IODescriptor descriptor) {
                  // etc
                }
                • 20. Re: extending classes which contains static methods
                  Carlo A
                  Thanks very much to darke (helpful answer) and to Walter Laan (correct answer). I've learned two good (they seems so to me) practice.
                  I modified the darke code using reflection (i used reflection two or three times in the last 8 years) so that derived InputOutput classes don't need change in InputOutput class.
                  Here the code:
                  import java.lang.reflect.InvocationTargetException;
                  import java.lang.reflect.Method;
                  import java.lang.reflect.Modifier;
                  
                  public class IODescriptionTest {
                  
                       public static void main(String[] args) {
                            InputOutput in = new DigitalInput("fc1");
                            InputOutput out = new DigitalOutput("y102");
                  
                            /* here i need the description of some InputOutput objects */
                            System.out.println("in.description()=" + in.description());
                            System.out.println("out.description()=" + out.description());
                  
                            /*
                             * here i need the description of a DigitalInput and a DigitalOutput without having a reference to the relative object
                             * and i cannot instantiate an object due to side effects.
                             */
                            System.out.println("\"fc2\" description=" + InputOutput.description(DigitalInput.class, "fc2"));
                            System.out.println("\"k11\" description=" + InputOutput.description(DigitalOutput.class, "k11"));
                            System.out.println("\"k12\" description=" + InputOutput.description(DerivedFromDigitalOutput.class, "k12"));
                  //          System.out.println("\"s11\" description=" + InputOutput.description(StrangeOutput.class, "k11")); compiler error becouse StrangeOutput class is not derived from InputOutput
                       }
                  }
                  
                  class Translator {
                       public static String translate(String key) {
                            return "translation of \"" + key + "\"";
                       }
                  }
                  
                  abstract class InputOutput {
                       String name;
                       public InputOutput(String name) { this.name = name; }
                  
                       public String description() {
                            return description(this.getClass(), name);
                       }
                  
                       public static String description(Class<? extends InputOutput> clazz, String name) {
                            return Translator.translate(getPrefix(clazz) + name);
                       }
                  
                       public static String getPrefix(Class clazz) {
                            String rv = "inputoutput.";
                            try {
                                 Method m = clazz.getMethod("getPrefix", new Class[] { });
                                 if (Modifier.isStatic(m.getModifiers())) {
                                      Object o = m.invoke(null);
                                      if (o instanceof String) {
                                           rv = (String)o;
                                      }
                                 }
                            } catch (NoSuchMethodException e) {
                            } catch (InvocationTargetException e) {
                            } catch (IllegalAccessException e) {
                            }
                            return rv;
                       }
                  }
                  
                  class DigitalInput extends InputOutput {
                       public static String getPrefix() { return "digital.input."; }
                       public DigitalInput(String name) { super(name); }
                  }
                  
                  class DigitalOutput extends InputOutput {
                       public static String getPrefix() { return "digital.output."; }
                       public DigitalOutput(String name) { super(name); }
                  }
                  
                  class DerivedFromDigitalOutput extends DigitalOutput {
                       public static String getPrefix() { return "derived.from.digital.output."; }
                       public DerivedFromDigitalOutput(String name) { super(name); }
                  }
                  
                  class StrangeOutput {
                       public static String getPrefix() { return "strange.output."; }
                       public StrangeOutput(String name) { }
                  }
                  And here my implementation adopting the suggestione from Walter:

                  public class IODescriptionTest {
                  
                       public static void main(String[] args) {
                            InputOutput in = new DigitalInput("fc1");
                            InputOutput out = new DigitalOutput("y102");
                  
                            /* here i need the description of some InputOutput objects */
                            System.out.println("in.description()=" + in.getDescription());
                            System.out.println("out.description()=" + out.getDescription());
                  
                            /*
                             * here i need the description of a DigitalInput and a DigitalOutput without having a reference to the relative object
                             * and i cannot instantiate an object due to side effects.
                             * Now i can create an instance of a IODescription!
                             */
                            IODescriptor fc2 = new DigitalInput.Descriptor("fc2");
                            System.out.println("\"fc2\" description=" + fc2.getDescription());
                  
                            IODescriptor k11 = new DigitalOutput.Descriptor("k11");
                            System.out.println("\"k11\" description=" + k11.getDescription());
                  
                            IODescriptor k12 = new DerivedFromDigitalOutput.Descriptor("k12");
                            System.out.println("\"k12\" description=" + k12.getDescription());
                       }
                  }
                  
                  class Translator {
                       public static String translate(String key) {
                            return "translation of \"" + key + "\"";
                       }
                  }
                  
                  interface IODescriptor {
                       String getName();
                       String getDescription();
                  }
                        
                  abstract class AbstractIODescriptor implements IODescriptor {
                       private final String name;
                       private final String descriptionKey;
                       public AbstractIODescriptor(String prefix, String name) {
                            this.name = name;
                            this.descriptionKey = prefix + name;
                       }
                       public String getName() { return name; }
                       public String getDescription() {
                            return Translator.translate(descriptionKey);
                       }
                  }
                  
                  abstract class InputOutput {
                       IODescriptor name;
                       public InputOutput(IODescriptor name) { this.name = name; }
                  
                       public String getDescription() {
                            return name.getDescription();
                       }
                  }
                  
                  
                  class DigitalInput extends InputOutput {
                       public DigitalInput(String name) { super(new Descriptor(name)); }
                       public static class Descriptor extends AbstractIODescriptor {
                            public Descriptor(String name) { super("digital.input.", name); }
                       }
                  }
                  
                  class DigitalOutput extends InputOutput {
                       public DigitalOutput(String name) { super(new Descriptor(name)); }
                       public static class Descriptor extends AbstractIODescriptor {
                            public Descriptor(String name) { super("digital.output.", name); }
                       }
                  }
                  
                  class DerivedFromDigitalOutput extends DigitalOutput {
                       public DerivedFromDigitalOutput(String name) { super(name); }
                  }
                  I don't know which is the better. From an OOP point of view i think the Walter solution is better. I could not figure out that I had to create a interface (IODescriptor), an abstract class (AbstractIODescriptor) and a concrete class (Descriptor) inside each class extends InputOutput.

                  Carlo
                  • 21. Re: extending classes which contains static methods
                    jschellSomeoneStoleMyAlias
                    Carlo A wrote:
                    What I don't understand is why (from an OOP point of view) the idea of override a static method (declared in an abstract class or in a interface) is so crazy to you.
                    Not sure what that statement means.

                    You can't do it in java. So the statement is meaningless.

                    You can do it in smalltalk. Far as I have ever been able to tell it certainly isn't used that much in smalltalk. Based on my own experience I doubt there are many situations where it is a good idea. Based on the questions on this site there are certainly many people that think they want to do it but I can't recall a single one where the proposed reason was a good one.

                    Also you can't do it in C# nor C++ and I have never seen any serious discussions that suggest such a feature is missing from those languages.
                    • 22. Re: extending classes which contains static methods
                      jschellSomeoneStoleMyAlias
                      Carlo A wrote:
                      Sorry, i don't want to put any word mouth to anybody (nevertheless be offensive). From your answer it seems (to me, but tell me if i'm wrong) that my question is very strange to you but i don't see any strangeness. If it is true that my question is strange please help me understand why: it's more important for me to understand this than the original question.
                      Ok....

                      People ask many things on this site (and others) in terms something like "this is the solution I want but I cant figure out how to make the language do it". And for some of them the answer is "the language doesn't do that", to which then often respond "why not".

                      However in terms of professional programming it doesn't really matter why a language doesn't do something because at the end of the day you need to deliver a product.

                      So that is the general answer to your question.

                      In addition as already pointed out your question resolves around you trying to force a solution on to the problem. Rather than presenting the problem and then looking for solutions. In the wide, wide universe of possibilities it is in unlikely (as a probability spanning all problems) that your business problem is so unusual that you actually need the feature that you think you need. The vast majority of problems are 'best' solved by the standard idioms.

                      But presume that someone (perhaps you) have one of the very unique problems that because of business (not technical idealism) needs would benefit from some little used feature. But that means that at some time in the future a maintenance developer, to support the code, will need to learn that obscure feature and will need to learn best practices for using it (difficult since it is obscure.) So even though that obscure feature seemed 'best' it would need to actually be significantly better in a objective sense versus an implementation using the standard idioms.
                      1 2 Previous Next