- Category: Programming Guides & Tutorials
- Published on Thursday, 01 September 2011 05:00
- Written by Prabhu Selvakumar
Object Orientation Summary
We started the chapter by discussing the importance of encapsulation in good OO design, and then we talked about how good encapsulation is implemented: with private instance variables and public getters and setters.
Next, we covered the importance of inheritance; so that you can grasp overriding, overloading, polymorphism, reference casting, return types, and constructors.
We covered IS-A and HAS-A. IS-A is implemented using inheritance, and HAS-A is implemented by using instance variables that refer to other objects.
Polymorphism was next. Although a reference variable's type can't be changed, it can be used to refer to an object whose type is a subtype of its own. We learned how to determine what methods are invocable for a given reference variable.
We looked at the difference between overridden and overloaded methods, learning that an overridden method occurs when a subclass inherits a method from a superclass, and then re-implements the method to add more specialized behavior. We learned that, at runtime, the JVM will invoke the subclass version on an
instance of a subclass, and the superclass version on an instance of the superclass. Abstract methods must be "overridden" (technically, abstract methods must be implemented, as opposed to overridden, since there really isn't anything to override.
We saw that overriding methods must declare the same argument list and return type (or, as of Java 5, they can return a subtype of the declared return type of the superclass overidden method), and that the access modifier can't be more restrictive. The overriding method also can't throw any new or broader checked exceptions that weren't declared in the overridden method. You also learned that the overridden method can be invoked using the syntax super.doSomething();.
Overloaded methods let you reuse the same method name in a class, but with different arguments (and, optionally, a different return type). Whereas overriding methods must not change the argument list, overloaded methods must. But unlike overriding methods, overloaded methods are free to vary the return type, access
modifier, and declared exceptions any way they like.
We learned the mechanics of casting (mostly downcasting), reference variables, when it's necessary, and how to use the instanceof operator.
Implementing interfaces came next. An interface describes a contract that the implementing class must follow. The rules for implementing an interface are similar to those for extending an abstract class. Also remember that a class can implement more than one interface, and that interfaces can extend another interface.
We also looked at method return types, and saw that you can declare any return type you like (assuming you have access to a class for an object reference return type), unless you're overriding a method. Barring a covariant return, an overriding method must have the same return type as the overridden method of the superclass. We saw that while overriding methods must not change the return type, overloaded methods can (as long as they also change the argument list).
Finally, you learned that it is legal to return any value or variable that can be implicitly converted to the declared return type. So, for example, a short can be returned when the return type is declared as an int. And (assuming Horse extends Animal), a Horse reference can be returned when the return type is declared an Animal.
We covered constructors in detail, learning that if you don't provide a constructor for your class, the compiler will insert one. The compiler-generated constructor is called the default constructor, and it is always a no-arg constructor with a no-arg call to super(). The default constructor will never be generated if there is even a single constructor in your class (regardless of the arguments of that constructor), so if you need more than one constructor in your class and you want a no-arg constructor,
you'll have to write it yourself. We also saw that constructors are not inherited, and that you can be confused by a method that has the same name as the class (which is legal). The return type is the giveaway that a method is not a constructor, since constructors do not have return types.
We saw how all of the constructors in an object's inheritance tree will always be invoked when the object is instantiated using new. We also saw that constructors can be overloaded, which means defining constructors with different argument lists. A constructor can invoke another constructor of the same class using the keyword
this(), as though the constructor were a method named this(). We saw that every constructor must have either this() or super() as the first statement.
We looked at static methods and variables. Static members are tied to the class, not an instance, so there is only one copy of any static member. A common mistake is to attempt to reference an instance variable from a static method. Use the class name with the dot operator to access static members.
We discussed the OO concepts of coupling and cohesion. Loose coupling is the desirable state of two or more classes that interact with each other only through their respective API's. Tight coupling is the undesirable state of two or more classes that know inside details about another class, details not revealed in the
class's API. High cohesion is the desirable state of a single class whose purpose and responsibilities are limited and well-focused.
And once again, you learned that the exam includes tricky questions designed largely to test your ability to recognize just how tricky the questions can be.
blog comments powered by Disqus