发布新日志

  • Upcasting

    2014-09-02 14:33:55

    From http://stackoverflow.com/questions/5361999/whats-the-need-to-use-upcasting-in-java


    In most situations, the upcast is entirely unnecessary and has no effect. However, there are situations where the presence of the upcast changes the meaning of the statement / expression.

    One situation where it is necessary to use upcasting in Java is when you want to force a specific method override to be used; e.g. suppose that we have overloaded methods:

    public void doIt(Object o)...
    public void doIt(String s)...

    If I have a String and I want to call the first overload rather than the second, I have to do this:

    String arg = ...
    
    doIt((Object) arg);

    A related case is:

    doIt((Object) null);

    where the code won't compile without the type cast. (I'm not sure if this counts as an upcast, but here it is anyway.)

    A second situation involves varadic parameters:

    public void doIt(Object... args)...
    
    Object[] foo = ...
    
    doIt(foo);  // passes foo as the argument array
    doIt((Object) foo); // passes new Object[]{foo} as the argument array.

    A third situation is when performing operations on primitive numeric types; e.g.

    int i1 = ...
    int i2 = ...
    long res = i1 + i2;           // 32 bit signed arithmetic ... might overflow
    long res2 = ((long) i1) + i2; // 64 bit signed arithmetic ... won't overflow
  • "this" keyword

    2014-09-02 14:27:07

    The following is a copy & paste from here, but explains very well all different uses of the this keyword:

    Definition: Java’s this keyword is used to refer the current instance of the method on which it is used.

    Following are the ways to use this:

    1. To specifically denote that the instance variable is used instead of static or local variable. That is,

      private String javaFAQ;
      void methodName(String javaFAQ) {
          this.javaFAQ = javaFAQ;
      }

      Here this refers to the instance variable. Here the precedence is high for the local variable. Therefore the absence of the this denotes the local variable. If the local variable that is parameter’s name is not same as instance variable then irrespective of this is used or not it denotes the instance variable.

    2. This is used to refer the constructors

       public JavaQuestions(String javapapers) {
           this(javapapers, true);
       }

      This invokes the constructor of the same java class which has two parameters.

    3. This is used to pass the current java instance as parameter

      obj.itIsMe(this);
    4. Similar to the above this can also be used to return the current instance

      CurrentClassName startMethod() {
           return this;
      }

      Note: This may lead to undesired results while used in inner classes in the above two points. Since this will refer to the inner class and not the outer instance.

    5. This can be used to get the handle of the current class

      Class className = this.getClass(); // this methodology is preferable in java

      Though this can be done by

      Class className = ABC.class; // here ABC refers to the class name and you need to k
  • Inheritance vs Composition

    2014-09-02 11:53:24

    From http://www.artima.com/designtechniques/compoinh5.html


    a few guidelines that reflect how I tend to select between composition and inheritance.

    Make sure inheritance models the is-a relationship
    My main guiding philosophy is that inheritance should be used only when a subclass is-a superclass. In the example above, an Apple likely is-a Fruit, so I would be inclined to use inheritance.

    An important question to ask yourself when you think you have an is-a relationship is whether that is-a relationship will be constant throughout the lifetime of the application and, with luck, the lifecycle of the code. For example, you might think that an Employee is-a Person, when really Employee represents a role that a Person plays part of the time. What if the person becomes unemployed? What if the person is both an Employee and a Supervisor? Such impermanent is-a relationships should usually be modelled with composition.

    Don't use inheritance just to get code reuse
    If all you really want is to reuse code and there is no is-a relationship in sight, use composition.

    Don't use inheritance just to get at polymorphism
    If all you really want is polymorphism, but there is no natural is-a relationship, use composition with interfaces. I'll be talking about this subject next month.

  • Inheritance vs Delegation

    2014-09-02 11:16:36

    Found this very good explanation here
    http://www.jguru.com/faq/view.jsp?EID=27916


    Both delegation and inheritance are important concepts in object-oriented software design, but not everyone would label them as patterns. In particular, the seminal book on design patterns by the “Gang of Four” contains a discussion of inheritance and delegation, but the authors do not treat these topics as specific patterns. It is reasonable to think of them as design concepts which are more general than specific design patterns.

    Inheritance is a relationship between two classes where one class, called a subclass in this context, inherits the attributes and operations of another class, called its superclass. Inheritance can be a powerful design/reuse technique, especially when it is used in the context of the Liskov Substitution Principle. (The article by Robert Martin at http://www.objectmentor.com/publications/lsp.pdf provides an excellent explanation of the ideas behind Barbara Liskov’s original paper on using inheritance correctly.) The primary advantages of inheritance are

    1. it is directly supported by object-oriented languages, and
    2. it provides the context for polymorphism in strongly-typed object-oriented languages such as C++ and Java.
    But since the inheritance relationship is defined at compile-time, a class can’t change its superclass dynamically during program execution. Moreover, modifications to a superclass automatically propagate to the subclass, providing a two-edged sword for software maintenance and reuse. In summary, inheritance creates a strong, static coupling between a superclass and its subclasses.

    Delegation can be viewed as a relationship between objects where one object forwards certain method calls to another object, called its delegate. Delegation can also a powerful design/reuse technique. The primary advantage of delegation is run-time flexibility – the delegate can easily be changed at run-time. But unlike inheritance, delegation is not directly supported by most popular object-oriented languages, and it doesn’t facilitate dynamic polymorphism.

    As a simple example, consider the relationship between a Rectangle class and a Window class. With inheritance, a Window class would inherit its rectangular properties from class Rectangle. With delegation, a Window object would maintain a reference or pointer to a Rectangle object, and calls to rectangle-like methods of the Window object would be delegated to corresponding methods of the Rectangle object.

    Now let’s consider a slightly more complex example. Suppose employees can classified based on how they are paid; e.g., hourly or salaried. Using inheritance, we might design three classes: an Employee class which encapsulates the functionality common to all employees, and two subclasses HourlyEmployee and SalariedEmployee which encapsulates pay-specific details. While this design might be suitable for some applications, we would encounter problems in a scenario where a person changes, say from hourly to salaried. The class of an object and the inheritance relationship are both static, and objects can’t change their class easily (but see the State pattern for tips on how to fake it).

    A more flexible design would involve delegation – an Employee object could delegate pay-related method calls to an object whose responsibilities focused solely on how the employee is paid. In fact, we might still use inheritance here in a slightly different manner by creating an abstract class (or interface) called PayClassification with two subclasses HourlyPayClassification and SalariedPayClassification which implement classification-specific computations. Using delegation as shown, it would be much easier to change the pay classification of an existing Employee object.

    This second example illustrates an important point: In implementing delegation, we often want the capability to replace the delegate with another object, possibly of a different class. Therefore delegation will often use inheritance and polymorphism, with classes of potential delegates being subclasses of an abstract class which encapsulates general delegate responsibilities.

    One final point. Sometimes, the choice between delegation and inheritance is driven by external factors such as programming language support for multiple inheritance or design constraints requiring polymorphism. Consider threads in Java. You can associate a class with a thread in one of two ways: either by extending (inheriting) directly from class Thread, or by implementing the Runnable interface and then delegating to a Thread object. Often the approach taken is based on the restriction in Java that a class can only extend one class (i.e., Java does not support multiple inheritance). If the class you want to associate with a thread already extends some other class in the design, then you would have to use delegation; otherwise, extending class Thread would usually be the simpler approach.
     
Open Toolbar