OOP with Java Module 3 Notes (1) (1)
OOP with Java Module 3 Notes (1) (1)
Inheritance , Interfaces
Inheritance
Inheritance is one of the cornerstones of object-oriented programming
because it allows the creation of hierarchical classifications. Using
inheritance, you can create a general class that defines traits common to a set
of related items. This class can then be inherited by other, more specific
classes, each adding those things that are unique to it. In the terminology of
Java, a class that is inherited is called a superclass. The class that does the
inheriting is called a subclass. Therefore, a subclass is a specialized version of
a superclass. It inherits all of the members defined by the superclass and adds
its own, unique elements.
A class that is inherited is called a superclass. The class that does the
inheriting is called a subclass. Therefore, a subclass is a specialized version of
a superclass.
To inherit a class, you simply incorporate the definition of one class into
another by using the extends keyword.
The general form of a class declaration that inherits a superclass is shown
here:
Using super
Subclass needs to refer to its immediate superclass, it can do so by use of the
keyword super.
Super has two general forms. The first calls the superclass’ constructor. The
second is used to access a member of the superclass that has been hidden by a
member of a subclass.
super(arg-list);
vol = myclone.volume();
System.out.println("Volume of myclone is " + vol);
System.out.println("Weight of myclone is " + myclone.weight);
System.out.println();
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
System.out.println("Weight of mycube is " + mycube.weight);
System.out.println();
}}
This program generates the following output:
Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3
Volume of mybox2 is 24.0
Weight of mybox2 is 0.076
Volume of mybox3 is -1.0
Weight of mybox3 is -1.0
Volume of myclone is 3000.0
Weight of myclone is 34.3
Volume of mycube is 27.0
Weight of mycube is 2.0
A Second Use for super
The second form of super acts somewhat like this, except that it always refers
to the superclass of the subclass in which it is used. This usage has the
following general form: super.member
Here, member can be either a method or an instance variable. This second
form of super is most applicable to situations in which member names of a
subclass hide members by the same name in the superclass.
// Using super to overcome name hiding.
class A {
int i; }
// Create a subclass by extending class A.
class B extends A {
int i; // this i hides the i in A
B(int a, int b) {
super.i = a; // i in A
i = b; // i in B
}
void show() {
System.out.println("i in superclass: " + super.i);
System.out.println("i in subclass: " + i);
}}
class UseSuper {
public static void main(String args[]) {
B subOb = new B(1, 2);
subOb.show();
}}
This program displays the following:
i in superclass: 1
i in subclass: 2
// Add weight.
class BoxWeight extends Box {
double weight; // weight of box
// construct clone of an object
BoxWeight(BoxWeight ob) { // pass object to constructor
super(ob);
weight = ob.weight;
}
// constructor when all parameters are specified
BoxWeight(double w, double h, double d, double m) {
super(w, h, d); // call superclass constructor
weight = m; }
// default constructor
BoxWeight() {
super();
weight = -1; }
// constructor used when cube is created
BoxWeight(double len, double m) {
super(len);
weight = m; }
}
// Add shipping costs.
class Shipment extends BoxWeight {
double cost;
// construct clone of an object
Shipment(Shipment ob) { // pass object to constructor
super(ob);
cost = ob.cost;
}
// constructor when all parameters are specified
Shipment(double w, double h, double d,
double m, double c) {
super(w, h, d, m); // call superclass constructor
cost = c;
}
// default constructor
Shipment() {
super();
cost = -1; }
// constructor used when cube is created
Shipment(double len, double m, double c) {
super(len, m);
cost = c; }
}
class DemoShipment {
public static void main(String args[]) {
Shipment shipment1 =
new Shipment(10, 20, 15, 10, 3.41);
Shipment shipment2 =
new Shipment(2, 3, 4, 0.76, 1.28);
double vol;
vol = shipment1.volume();
System.out.println("Volume of shipment1 is " + vol);
System.out.println("Weight of shipment1 is + shipment1.weight);
System.out.println("Shipping cost: $" + shipment1.cost);
System.out.println();
vol = shipment2.volume();
System.out.println("Volume of shipment2 is " + vol);
System.out.println("Weight of shipment2 is " + shipment2.weight);
System.out.println("Shipping cost: $" + shipment2.cost);} }
The output of this program is shown here
Volume of shipment1 is 3000.0
Weight of shipment1 is 10.0
Shipping cost: $3.41
Method Overriding
In a class hierarchy, when a method in a subclass has the same name and type
signature as a method in its superclass, then the method in the subclass is said
to override the method in the superclass.
When an overridden method is called from within its subclass, it will always
refer to the version of that method defined by the subclass.
The version of the method defined by the superclass will be hidden.
// Method overriding.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b; }
// display i and j
void show() {
System.out.println("i and j: " + i + " " + j);
}}
class B extends A {
int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
// display k – this overrides show() in A
void show() {
System.out.println("k: " + k);
}
}
class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show(); // this calls show() in B
}
}
The output produced by this program is shown here:
k: 3
Dynamic Method Dispatch
If there were nothing more to method overriding than a name space
convention, then it would be, at best, an interesting curiosity, but of little real
value. However, this is not the case. Method overriding forms the basis for
one of Java’s most powerful concepts: dynamic method dispatch.
Dynamic method dispatch is the mechanism by which a call to an overridden
method is resolved at run time, rather than compile time.
Dynamic method dispatch is important because this is how Java implements
run-time polymorphism. it is the type of the object being referred to (not the
type of the reference variable) that determines which version of an overridden
method will be executed.
// Dynamic Method Dispatch
class A {
void callme() {
System.out.println("Inside A's callme method");
}}
class B extends A {
// override callme()
void callme() {
System.out.println("Inside B's callme method");
}
}
class C extends A {
// override callme()
void callme() {
System.out.println("Inside C's callme method");
}
}
class Dispatch {
public static void main(String args[]) {
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}
The output from the program is shown here:
Inside A's callme method
Inside B's callme method
Inside C's callme method
Using Abstract Classes
A class which is declared with the abstract keyword is known as an
abstract class in Java. It can have abstract and non-abstract methods (method
with the body).
The keyword final has three uses. First, it can be used to create the equivalent
of a named constant.The other two uses of final apply to inheritance .
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
//... }
The Object Class
There is one special class, Object, defined by Java. All other classes are
subclasses of Object. That is, Object is a superclass of all other classes.
This means that a reference variable of type Object can refer to an object of
any other class. Also, since arrays are implemented as classes, a variable of
type Object can also refer to any array.
The reason is, abstract classes may contain non-final variables, whereas
variables in the interface are final, public, and static.
// A simple interface
interface Player
{
final int id = 10;
int move();
}
Relationship Between Class and Interface
A class can extend another class similar to this an interface can extend another
interface. But only a class can extend to another interface, and vice-versa is
not allowed.
Difference Between Class and Interface
Although Class and Interface seem the same there have certain differences
between Classes and Interface. The major differences between a class and an
interface are mentioned below:
// A simple interface
interface In1 {
In the past, if a new method were added to a popular, widely used interface,
then the addition of that method would break existing code because no
implementation would be found for that new method. The default method
solves this problem by supplying an implementation that will be used if no
other implementation is explicitly provided. Thus, the addition of a default
method will not cause pre existing code to break. Another motivation for the
default method was the desire to specify methods in an interface that are,
essentially, optional, depending on how the interface is used.
An interface default method is defined similar to the way a method is defined
by a class.
The primary difference is that the declaration is preceded by the keyword
default.