Showing posts with label inheritance. Show all posts
Showing posts with label inheritance. Show all posts

Friday, 24 June 2011

Compiling cyclic dependency in Java

I recently cam across– If there is cyclic dependency between classes A, B and C. How do you go about compiling them in java? Apparently, that came up in an interview for someone.
Well, I don’t know what kind of dependency that person had in mind when asking this question – But I had not heard of anything being needed to compile in cases of cyclic dependencies as described below. Check out the code below – At least the current version of Java is clever enough that  you need to do nothing special to compile it.
Maybe this was a problem in old versions of Java and interviewers are still stuck looking for answers that are incorrect. Check out the demo code below -
package test;
class A{
A(){
new B();
}
}

package test;
class B{
B(){
new C();
}
}

package test;
class C{
C(){
new A();
}
}

Of course, trying to instantiate any of the above classes would lead to a StackOverflowError.

Saturday, 11 June 2011

How to force the subclasses of a concrete class to override a method?

There is no such real world scenario where a concrete entity will want to force a more specific entity to override its method. If it is to be overridden then why not make the super class as abstract.

Anyways, the logic behind the interview questions being asked now a days is something which requires best talent from the psychology field.

Solution: The solution which I have come up with for the above Java Interview question is to use the instanceof operator in the super class and throw an exception if the instance on which method is being invoked is found to be of the sub class. The sample program showing this scenario follows:

Though still its not like generating compile time error but gives exception at runtime.  Do suggest if you have a better solution.

public class Test{

void test() {
if ((this instanceof Test1)) {
throw new RuntimeException();
}
System.out.println("passed");
}

public static void main(String[] args) {
Test t1 = new Test();
Test1 t2 = new Test1();

t1.test();
t2.test();
}

}
class Test1 extends Test {

}

The output of above program is:
passed
Exception in thread "main" java.lang.RuntimeException
at Test.test(Test.java:5)
at Test.main(Test.java:15)

Tuesday, 24 May 2011

Solution to Square rectangle problem

We have already gone through this problem here.
So inheritance is not always useful, but composition may be the key sometimes.

public class Square  
{
private Rectangle r;
public void SetWidth (double x) { r.SetWidth (x); r.SetHeight (x); }
public void SetHeight (double x) { r.SetWidth (x); r.SetHeight (x); }
public void GetWidth () { return r.GetWidth; }
public void GetHeight() { return r. GetHeight; }
public void GetArea () { return r. GetArea; }
}

So it solves our problem.

Tuesday, 1 February 2011

Composition vs Inheritance 2

Dynamic binding, polymorphism, and change
When you establish an inheritance relationship between two classes, you get to take advantage of dynamic binding and polymorphism. Dynamic binding means the JVM will decide at runtime which method implementation to invoke based on the class of the object. Polymorphism means you can use a variable of a superclass type to hold a reference to an object whose class is the superclass or any of its subclasses.
One of the prime benefits of dynamic binding and polymorphism is that they can help make code easier to change. If you have a fragment of code that uses a variable of a superclass type, such as Fruit, you could later create a brand new subclass, such as Banana, and the old code fragment will work without change with instances of the new subclass. If Banana overrides any of Fruit's methods that are invoked by the code fragment, dynamic binding will ensure that Banana's implementation of those methods gets executed. This will be true even though class Banana didn't exist when the code fragment was written and compiled.
Thus, inheritance helps make code easier to change if the needed change involves adding a new subclass. This, however, is not the only kind of change you may need to make.
Changing the superclass interface
In an inheritance relationship, superclasses are often said to be "fragile," because one little change to a superclass can ripple out and require changes in many other places in the application's code. To be more specific, what is actually fragile about a superclass is its interface. If the superclass is well-designed, with a clean separation of interface and implementation in the object-oriented style, any changes to the superclass's implementation shouldn't ripple at all. Changes to the superclass's interface, however, can ripple out and break any code that uses the superclass or any of its subclasses. What's more, a change in the superclass interface can break the code that defines any of its subclasses.
For example, if you change the return type of a public method in class Fruit (a part of Fruit's interface), you can break the code that invokes that method on any reference of type Fruit or any subclass of Fruit. In addition, you break the code that defines any subclass of Fruit that overrides the method. Such subclasses won't compile until you go and change the return value of the overridden method to match the changed method in superclass Fruit.
Inheritance is also sometimes said to provide "weak encapsulation," because if you have code that directly uses a subclass, such as Apple, that code can be broken by changes to a superclass, such as Fruit. One of the ways to look at inheritance is that it allows subclass code to reuse superclass code. For example, if Apple doesn't override a method defined in its superclass Fruit, Apple is in a sense reusing Fruit's implementation of the method. But Apple only "weakly encapsulates" the Fruit code it is reusing, because changes to Fruit's interface can break code that directly uses Apple.

Composition vs Inheritance

The composition alternative
Given that the inheritance relationship makes it hard to change the interface of a superclass, it is worth looking at an alternative approach provided by composition. It turns out that when your goal is code reuse, composition provides an approach that yields easier-to-change code.
Code reuse via inheritance
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:

class Fruit {

// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {

System.out.println("Peeling is appealing.");
return 1;
}
}

class Apple extends Fruit {
}

class Example1 {

public static void main(String[] args) {

Apple apple = new Apple();
int pieces = apple.peel();
}
}
When you run the Example1 application, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation of peel(). If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit.
Here's what that would look like:

class Peel {

private int peelCount;

public Peel(int peelCount) {
this.peelCount = peelCount;
}

public int getPeelCount() {

return peelCount;
}
//...
}

class Fruit {

// Return a Peel object that
// results from the peeling activity.
public Peel peel() {

System.out.println("Peeling is appealing.");
return new Peel(1);
}
}

// Apple still compiles and works fine
class Apple extends Fruit {
}

// This old implementation of Example1
// is broken and won't compile.
class Example1 {

public static void main(String[] args) {

Apple apple = new Apple();
int pieces = apple.peel();
}
}
Code reuse via composition
Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:

class Fruit {

// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {

System.out.println("Peeling is appealing.");
return 1;
}
}

class Apple {

private Fruit fruit = new Fruit();

public int peel() {
return fruit.peel();
}
}

class Example2 {

public static void main(String[] args) {

Apple apple = new Apple();
int pieces = apple.peel();
}
}
In the composition approach, the subclass becomes the "front-end class," and the superclass becomes the "back-end class." With inheritance, a subclass automatically inherits an implemenation of any non-private superclass method that it doesn't override. With composition, by contrast, the front-end class must explicitly invoke a corresponding method in the back-end class from its own implementation of the method. This explicit call is sometimes called "forwarding" or "delegating" the method invocation to the back-end object.
The composition approach to code reuse provides stronger encapsulation than inheritance, because a change to a back-end class needn't break any code that relies only on the front-end class. For example, changing the return type of Fruit's peel() method from the previous example doesn't force a change in Apple's interface and therefore needn't break Example2's code.
Here's how the changed code would look:

class Peel {

private int peelCount;

public Peel(int peelCount) {
this.peelCount = peelCount;
}

public int getPeelCount() {

return peelCount;
}
//...
}

class Fruit {

// Return int number of pieces of peel that
// resulted from the peeling activity.
public Peel peel() {

System.out.println("Peeling is appealing.");
return new Peel(1);
}
}

// Apple must be changed to accomodate
// the change to Fruit
class Apple {

private Fruit fruit = new Fruit();

public int peel() {

Peel peel = fruit.peel();
return peel.getPeelCount();
}
}

// This old implementation of Example2
// still works fine.
class Example1 {

public static void main(String[] args) {

Apple apple = new Apple();
int pieces = apple.peel();
}
}
This example illustrates that the ripple effect caused by changing a back-end class stops (or at least can stop) at the front-end class. Although Apple's peel() method had to be updated to accommodate the change to Fruit, Example2 required no changes.

Comparing composition and inheritance 4


So how exactly do composition and inheritance compare? Here are several points of comparison:

  • It is easier to change the interface of a back-end class (composition) than a superclass (inheritance). As the previous example illustrated, a change to the interface of a back-end class necessitates a change to the front-end class implementation, but not necessarily the front-end interface. Code that depends only on the front-end interface still works, so long as the front-end interface remains the same. By contrast, a change to a superclass's interface can not only ripple down the inheritance hierarchy to subclasses, but can also ripple out to code that uses just the subclass's interface.
  • It is easier to change the interface of a front-end class (composition) than a subclass (inheritance). Just as superclasses can be fragile, subclasses can be rigid. You can't just change a subclass's interface without making sure the subclass's new interface is compatible with that of its supertypes. For example, you can't add to a subclass a method with the same signature but a different return type as a method inherited from a superclass. Composition, on the other hand, allows you to change the interface of a front-end class without affecting back-end classes.
  • Composition allows you to delay the creation of back-end objects until (and unless) they are needed, as well as changing the back-end objects dynamically throughout the lifetime of the front-end object. With inheritance, you get the image of the superclass in your subclass object image as soon as the subclass is created, and it remains part of the subclass object throughout the lifetime of the subclass.
  • It is easier to add new subclasses (inheritance) than it is to add new front-end classes (composition), because inheritance comes with polymorphism. If you have a bit of code that relies only on a superclass interface, that code can work with a new subclass without change. This is not true of composition, unless you use composition with interfaces. Used together, composition and interfaces make a very powerful design tool. I'll talk about this approach in next month's Design Techniques article.
  • The explicit method-invocation forwarding (or delegation) approach of composition will often have a performance cost as compared to inheritance's single invocation of an inherited superclass method implementation. I say "often" here because the performance really depends on many factors, including how the JVM optimizes the program as it executes it.
  • With both composition and inheritance, changing the implementation (not the interface) of any class is easy. The ripple effect of implementation changes remain inside the same class.

Inheritance vs Composition

Choosing between composition and inheritance
So how do all these comparisons between composition and inheritance help you in your designs? Here are 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.

Saturday, 23 October 2010

Design Hints for Inheritance

We want to end this chapter with some hints that we have found useful when using inheritance.
  1. Place common operations and fields in the superclass.
    This is why we put the name field into the Person class rather than replicating it in the Employee and Student classes.
  2. Don't use protected fields.
    Some programmers think it is a good idea to define most instance fields as protected, "just in case," so that subclasses can access these fields if they need to. However, the protected mechanism doesn't give much protection, for two reasons. First, the set of subclasses is unbounded—anyone can form a subclass of your classes and then write code that directly accesses protected instance fields, thereby breaking encapsulation. And second, in the Java programming language, all classes in the same package have access to protected fields, whether or not they are subclasses.
    However, protected methods can be useful to indicate methods that are not ready for general use and should be redefined in subclasses. The clone method is a good example.
  3. Use inheritance to model the "is–a" relationship.
    Inheritance is a handy code-saver, and sometimes people overuse it. For example, suppose we need a Contractor class. Contractors have names and hire dates, but they do not have salaries. Instead, they are paid by the hour, and they do not stay around long enough to get a raise. There is the temptation to form a subclass Contractor from Employee and add an hourlyWage field.
    class Contractor extends Employee
    { . . .
    private double hourlyWage;
    }

    This is not a good idea, however, because now each contractor object has both a salary and hourly wage field. It will cause you no end of grief when you implement methods for printing paychecks or tax forms. You will end up writing more code than you would have by not inheriting in the first place.
    The contractor/employee relationship fails the "is–a" test. A contractor is not a special case of an employee.
  4. Don't use inheritance unless all inherited methods make sense.
    Suppose we want to write a Holiday class. Surely every holiday is a day, and days can be expressed as instances of the GregorianCalendar class, so we can use inheritance.
    class Holiday extends GregorianCalendar { . . . }

    Unfortunately, the set of holidays is not closed under the inherited operations. One of the public methods of GregorianCalendar is add. And add can turn holidays into nonholidays:
    Holiday christmas;
    christmas.add(Calendar.DAY_OF_MONTH, 12);

    Therefore, inheritance is not appropriate in this example.
  5. Don't change the expected behavior when you override a method.
    The substitution principle applies not just to syntax but, more important, to behavior. When you override a method, you should not unreasonably change its behavior. The compiler can't help you—it cannot check whether your redefinitions make sense. For example, you can "fix" the issue of the add method in the Holiday class by redefining add, perhaps to do nothing, or to throw an exception, or to move on to the next holiday.
    However, such a fix violates the substitution principle. The sequence of statements
    int d1 = x.get(Calendar.DAY_OF_MONTH);
    x.add(Calendar.DAY_OF_MONTH, 1);
    int d2 = x.get(Calendar.DAY_OF_MONTH);
    System.out.println(d2 - d1);

    should have the expected behavior, no matter whether x is of type GregorianCalendar or Holiday.
    Of course, therein lies the rub. Reasonable and unreasonable people can argue at length what the expected behavior is. For example, some authors argue that the substitution principle requires Manager.equals to ignore the bonus field because Employee.equals ignores it. These discussions are always pointless if they occur in a vacuum. Ultimately, what matters is that you do not circumvent the intent of the original design when you override methods in subclasses.
  6. Use polymorphism, not type information.
    Whenever you find code of the form

    if (x is of type 1)
       action1(x);
    else if (x is of type 2)
       action2(x);
    think polymorphism.
    Do action1 and action2 represent a common concept? If so, make the concept a method of a common superclass or interface of both types. Then, you can simply call
    x.action();

    and have the dynamic dispatch mechanism inherent in polymorphism launch the correct action.
    Code using polymorphic methods or interface implementations is much easier to maintain and extend than code that uses multiple type tests.
  7. Don't overuse reflection.
    The reflection mechanism lets you write programs with amazing generality, by detecting fields and methods at run time. This capability can be extremely useful for systems programming, but it is usually not appropriate in applications. Reflection is fragile—the compiler cannot help you find programming errors. Any errors are found at run time and result in exceptions.

Sunday, 26 September 2010

Interfaces in java

Interfaces in java are the pure abstract classes in which functions are given...which are to be implemented by all the class implementing those interface.

Note that in java interface naming is like Iterable, etc...i.e ending with able many times.

Wednesday, 28 July 2010

Final keyword in java

A java variable can be declared using the keyword final. Then the final variable can be assigned only once. You cannot be modify it afterwards. However it can be used in different contexts.

Following are the places where final can be used:

  1. variables: a final variable can be set once and only once.
    blank final variable - A variable that is declared as final and not initialized is called a blank final variable. A blank final variable forces the constructors to initialise it.
  2. fields: a final field can also be set only once, by the constructor of the class which defines it.
  3. methods: a final method cannot be overridden nor hidden.
    final parameters - values of the parameters cannot be changed after initialization.
  4. classes: a final class cannot be extended or inherited.

Other effects of final:

  • Java local classes can only reference local variables and parameters that are declared as final.
  • A visible advantage of declaring a java variable as static final is, the compiled java class results in faster performance.

Notice how using final is an entirely negative act. The final keyword works by subtracting, limiting default language mechanisms: the ability to override a method, to set a variable or a field. The motivations behind using final fall into three broad categories: correctness, robustness, and finally performance. Seeing them 1 by one.

Final Variables

Final variables come in handy in mostly three situations: 

a) Declare Constants

Coupled with static, final is used to flag constants. This usage is well-known to all Java programmers, so I won't expand much on it. It is useful to know that the value of a field declared constant in that manner will be computed statically if possible, at compile-time.
private static final int ERROR_CODE = 1 + 3 * 4 / 2;
public static final String ERROR_MESSAGE = "An error
occurred with code="
+ ERROR_CODE;

The compiler will compute the value for ERROR_CODE, concatenate the string equivalent of the result, and assign the resulting String to ERROR_MESSAGE.


b) Final Parameters

The following sample declares final parameters:




public void doSomething(final int i, final int j){
// ...
}
final is used here to ensure the two indexes i and j won't accidentally be reset by the method. It's a handy way to protect against an insidious bug that erroneously changes the value of your parameters. Generally speaking, short methods are a better way to protect from this class of errors, but final parameters can be a useful addition to your coding style.
Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.


c) Anonymous Local Classes

The third situation involving final variables is actually mandated by language semantics. In that situation, the Java compiler won't let you use a variable unless it is declared final. This situation arises with closures, also known as anonymous local classes. Local classes can only reference local variables and parameters that are declared final.





public void doSomething(int i, int j){
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};//note the semicolon here
}

The reason for this restriction becomes apparent if we shed some light on how local classes are implemented. An anonymous local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee in place, the local class is assured that its internal copies of the variables accurately reflect the actual local variables.


2. Final Fields

A final field can be assigned once and only once, and must be initialized by every constructor of the class that declares it. It is also possible to assign the field directly, in the same statement where it is defined. This simply reflects the fact that such shortcut assignments are compiled into a synthetic constructor. E.g. both the following code samples are correct and strictly equivalent; the first is preferred for being shorter. Initializing outside constructor body

public class MyClass{
//initializing hereitself
private final int i = 2;
}

Initialising in constructor body



public class MyClass{
private final int i;
public MyClass()
{
i = 2;
}
}


3. Using final to Prevent Method Overriding



While method overriding is one of Java’s most powerful features, there will be times when you will want to prevent it from occurring. To disallow a method from being overridden, specify final as a modifier at the start of its declaration. Methods declared as final cannot be overridden. The following fragment illustrates final:


class A {

final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {

void meth() { // ERROR! Can't override.
System.out.println("Illegal!");
}
}

Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to
do so, a compile-time error will result.

Methods declared as final can sometimes provide a performance enhancement: The compiler is free to inline calls to them because it “knows” they will not be overridden by a subclass. When a small final method is called, often the Java compiler can copy the bytecode for the subroutine directly inline with the compiled code of the calling method, thus eliminating the costly overhead associated with a method call. Inlining is only an option with final methods. Normally, Java resolves calls to methods dynamically, at run
time. This is called late binding. However, since final methods cannot be overridden, a call to one can be resolved at compile time. This is called early binding.



4. Using final to Prevent Inheritance

Sometimes you will want to prevent a class from being inherited. To do this, precede the class declaration with final. Declaring a class as final implicitly declares all of its methods as final, too. As you might expect, it is illegal to declare a class as both abstract and final since an abstract class is incomplete by itself and relies upon its subclasses to provide complete implementations.
Here is an example of a final class:
final class A {
// ...
}
// The following class is illegal.
class B extends A { // ERROR! Can't subclass A
// ...
}


As the comments imply, it is illegal for B to inherit A since A is declared as final.


CPP vs Java on Final – Controversy


‘final’ should not be called as constants. Because when an array is declared as final, the state of the object stored in the array can be modified. You need to make it immutable in order not to allow modifcations. In general context constants will not allow to modify. In C++, an array declared as const will not allow the above scenario but java allows. So java’s final is not the general constant used across in computer languages.

A variable that is declared static final is closer to constants in general software terminology. You must instantiate the variable when you declare it static final.

Definition as per java language specification (third edition) – 4.12.4 is “A final variable may only be assigned to once.”(§4.1.2). See notes on final w.r.t Java memory model here -


Java language specification tries to redefine the meaning of constant in the following way!
We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).


Immutable Objects


Final is used to construct immutable objects in java. See – Immutable Objects