| Start |
|---|
| Abstract Classes An abstract class is a class marked with the An abstract class cannot be instantiated. It can be sub-classed (extended) as long as the sub-class is either also abstract, or implements all methods marked as abstract by super classes. An example of an abstract class: The class must be marked abstract, when it has at least one abstract method. An abstract method is a method that has no implementation. Other methods can be declared within an abstract class that have implementation in order to provide common code for any sub-classes. Attempting to instantiate this class will provide a compile error: However a class that extends Instances of inheriting classes also can be cast as the parent class (normal inheritance) and they provide a polymorphic effect when the abstract method is called. Abstract classes vs Interfaces Abstract classes and interfaces both provide a way to define method signatures while requiring the extending/implementing class to provide the implementation. There are two key differences between abstract classes and interfaces:
Methods declared in interfaces could not contain implementations, so abstract classes were used when it was useful to provide additional methods which implementations called the abstract methods. Java 8 allows interfaces to contain default methods (opens new window), usually implemented using the other methods of the interface (opens new window), making interfaces and abstract classes equally powerful in this regard. Anonymous subclasses of Abstract Classes As a convenience java allows for instantiation of anonymous instances of subclasses of abstract classes, which provide implementations for the abstract methods upon creating the new object. Using the above example this could look like this: |
Using 'final' to restrict inheritance and overriding Final classesWhen used in a Use-cases for final classesFinal classes can be combined with a Immutable classes should also be declared as From a practical perspective, declaring an immutable class to be One disadvantage of Final methodsThe Final methods are typically used when you want to restrict what a subclass can change in a class without forbidding subclasses entirely. The |
| Inheritance With the use of the Instances of Additional content can be added to a subclass. Doing so allows for additional functionality in the subclass without any change to the base class or any other subclasses from that same base class: Fields are also inherited:
In Java, each class may extend at most one other class. This is known as multiple inheritance, and while it is legal in some languages, Java does not permit it with classes. As a result of this, every class has an unbranching ancestral chain of classes leading to |
| The Liskov Substitution Principle Substitutability is a principle in object-oriented programming introduced by Barbara Liskov in a 1987 conference keynote stating that, if class This also applies when the type is an interface, where there doesn't need to any hierarchical relationship between the objects: Now the list contains objects that are not from the same class hierarchy. |
| Static Inheritance Static method can be inherited similar to normal methods, however unlike normal methods it is impossible to create "abstract (opens new window)" methods in order to force static method overriding. Writing a method with the same signature as a static method in a super class appears to be a form of overriding, but really this simply creates a new function hides the other. Running any of these classes produces the output: Note that unlike normal inheritance, in static inheritance methods are not hidden. You can always call the base Static fields hide each other in a similar way. |
| Abstract class and Interface usage: "Is-a" relation vs "Has-a" capability When to use abstract classes: To implement the same or different behaviour among multiple related objects When to use interfaces: to implement a contract by multiple unrelated objects Abstract classes create "is a" relations while interfaces provide "has a" capability. This can be seen in the code below: output: Key notes: TL;DR: Unrelated classes can have capabilities through interfaces, but related classes change the behaviour through extension of base classes. Refer to the Java documentation page (opens new window) to understand which one to use in a specific use case. Consider using abstract classes if...
Consider using interfaces if...
|
| Inheritance and Static Methods In Java, parent and child class both can have static methods with the same name. But in such cases implementation of static method in child is hiding (opens new window) parent class' implementation, it's not method overriding. For example: Static methods are bind to a class not to an instance and this method binding happens at compile time. Since in the first call to |
| Variable shadowing Variables are SHADOWED and methods are OVERRIDDEN. Which variable will be used depends on the class that the variable is declared of. Which method will be used depends on the actual class of the object that is referenced by the variable. |
| Narrowing and Widening of object references Casting an instance of a base class to a subclass as in : Casting an instance of a subclass to a base class as in: To illustrate, consider the following class declarations, and test code: The statement On the other hand, To prevent this situation, we need to add an explicit type-cast: The type-cast tells the compiler that we expect the value of Note that not all type-casts are valid. For example: The Java compiler knows that an instance that is type compatible with |
| Programming to an interface The idea behind programming to an interface is to base the code primarily on interfaces and only use concrete classes at the time of instantiation. In this context, good code dealing with e.g. Java collections will look something like this (not that the method itself is of any use at all, just illustration): while bad code might look like this: Not only the former can be applied to a wider choice of arguments, its results will be more compatible with code provided by other developers that generally adhere to the concept of programming to an interface. However, the most important reasons to use the former are:
So how can one easily apply the concept of programming to an interface when writing new code having in mind one particular implementation? One option that we commonly use is a combination of the following patterns:
The following example based on these principles is a simplified and truncated version of an RPC implementation written for a number of different protocols: The above interface is not supposed to be instantiated directly via a factory, instead we derive further more concrete interfaces, one for HTTP invocation and one for AMQP, each then having a factory and a builder to construct instances, which in turn are also instances of the above interface: Instances of And an invocation of a request is as easy as: Due to Java 8 permitting placing of static methods directly into interfaces, the intermediate factory has become implicit in the above code replaced with The corresponding instantiation would then turn into: The builder used above could look like this (although this is a simplification as the actual one permits defining of up to 15 parameters deviating from defaults). Note that the construct is not public, so it is specifically usable only from the above Generally, a builder can also be generated using a tool like FreeBuilder. Finally, the standard (and the only expected) implementation of this interface is defined as a package-local class to enforce the use of the interface, the factory and the builder: Meanwhile, this pattern proved to be very efficient in developing all our new code not matter how simple or complex the functionality is. |
| Overriding in Inheritance Overriding in Inheritance is used when you use a already defined method from a super class in a sub class, but in a different way than how the method was originally designed in the super class. Overriding allows the user to reuse code by using existing material and modifying it to suit the user's needs better. The following example demonstrates how Example: Output: A B Syntax
RemarksInheritance is often combined with generics so that the base class has one or more type parameters. See Creating a Generic Class (opens new window). |
Read Article
https://develop.horje.com/learn/1434/reference