1.2k likes | 1.31k Views
Inheritance. Inheritance is a form of software reuse in which a new class is created by absorbing an existing class’s members and embellishing them with new or modified capabilities.
E N D
Inheritance • Inheritance is a form of software reuse in which a new class is created by absorbing an existing class’s members and embellishing them with new or modified capabilities. • With inheritance, programmers save time during program development by reusing proven and debugged high-quality software. • This also increases the likelihood that a system will be implemented effectively. tMyn
When creating a class, rather than declaring completely new members, the programmer can designate that the new class should inherit the members of an existing class. • The existing class is called the base class, and the new class is the derived class. • Each derived class can become the base class for future derived classes. • A derived class normally adds its own fields and methods. • Therefore, a derived class is more specific than its base class and represents a more specialized group of objects. tMyn
Typically, the derived class exhibits the behaviors of its base class and additional behaviors that are specific to the derived class. • The direct base class is the base class from which the derived class explicitly inherits. • An indirect base class is any class above the direct base class in the class hierarchy, which defines the inheritance relationships between classes. • In Java, the class hierarchy begins with class Object (in package java.lang), which every class in Java directly or indirectly extends or inherits from. tMyn
All the classes that you define are derived classes by default – whether you like it or not. • You never need to specify the class Object as a base class in the definition of your classes – it happens automatically. • There are some interesting consequences of having Object as a universal base class. The discussion of those topics are beyond this module. tMyn
In the case of single inheritance, a class is derived from one direct base class, Figure 1. • Java does not support multiple inheritance. • In Java programmers can use interfaces to realize many of the benefits of multiple inheritance while avoiding the associated problems. tMyn
Single Inheritance HorseVehicle Chaise Wagon Figure 1. An example of an UML representation of the single inheritance. tMyn
We can use a Box class to describe a rectangular box – our definition of a Box object consists of just the three orthogonal dimensions. • We might describe a Carton class which has the same properties as a Box object plus the additional property of its composite material. • We might then specialize even further, by using the Carton definition to describe a class called FoodCarton – this will be a special kind of Carton which is designed to hold food, Figure 2. tMyn
length breadth height class Box More General Inherited members Each class has the properties of the class it is derived from, plus additional properties that differentiate it. class Carton length breadth height material Inherited members class FoodCarton length breadth height material contents More Specialized Figure 2. An example of a three level class hierarchy. tMyn
The Carton class is an extension of the Box class – you might say that the Carton class is derived from the specification of the Box class. • In a similar way, the FoodCarton class has been derived from the Cartoon class. • By following this process, we develop a hierarchy of interrelated classes. • In the hierarchy, one class is derived from another by adding extra properties – in other words, by specializing. tMyn
Given a class A, suppose that we create a new, specialized class B. • So the class A is called the base class and the B is called the derived class. • The derived class automatically contains all of the instance variables of the base class, and (with some restrictions which we will discuss) all the methods. • The derived class is said to inherit the instance variables and methods of the base class. tMyn
If class B is a derived class defined directly in terms of class A, then we say that class A is a direct base class of B. • We also say that B is derived from A. • In the example above, the class Carton is a direct base class of FoodCarton. • Because Carton is itself defined in terms of the class Box, we say that the class Box is an indirect base class of the class FoodCarton. • An object of the FoodCarton class will have inherited members from Carton – including the members that the Carton class inherited from the Box class. tMyn
In the diagram above, each class has all the properties of the Box class (on which it is based), and this illustrates precisely the mechanism of class inheritance. • The derived class has a complete set of instance variables and methods from the base class, plus its own instance variables and methods. • Thus, each derived class object contains a complete base class sub-object, plus other members. • When does inheritance take place? • There are a number of simple tests that you can employ. tMyn
The first is the is a kind of test: any derived class object is a kind of base class object. • In other words, a derived class should describe a subset of the objects represented by the base class. • For example: a class Dog might be derived from a class Animal. This makes sense because a dog is a kind of animal. • The is a kind of test is an excellent first check, but it’s not infallible. For example, suppose that we defined a class, Bird, that (among other things) reflected the fact that most birds can fly… tMyn
…but now an ostrich is a kind of bird, but it’s nonsense to derive a class Ostrich from the Bird class, because ostriches can’t fly!! • If your classes pass the is a kind of test, then you should double check by asking the following question: Is there anything I can say about (or demand of) the base class that’s inapplicable to the derived class? • If there is, then the derivation probably isn’t safe. tMyn
If your classes fail the is a kind of test, then you almost certainly shouldn’t use class derivation. • In this case, you could instead implement the has a test. • A class object passes the has a test, if it contains an instance of another class. • You can implement this situation by including an object of the second class as a data member of the first. • This type of dependence is called aggregation or composition. Those topics will be discussed later. tMyn
For example, consider a class Automobile. • This class is likely to contain major automobile components as its class members. • An automobile has an engine, has a transmission, has a chassis and has suspension. • So it makes sense for the Automobile class to contain objects of type Engine, Transmission, Chassis and Suspension. • But it is not true to say that an engine is a kind of automobile! • The first example demonstrates the fundamentals in a two level class hierarchy: tMyn
package Timosoft; import java.util.Scanner; import java.util.Locale; public class Box { double width, height, depth; Box() { System.out.println("Box constructor called."); setWidth(); setHeight(); setDepth(); } void setWidth() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb1=new Scanner(System.in); System.out.print("Enter the width, please: "); width=fromTheKb1.nextDouble(); } tMyn
void setHeight() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb2=new Scanner(System.in); System.out.print("Enter the height, please: "); height=fromTheKb2.nextDouble(); } void setDepth() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb3=new Scanner(System.in); System.out.print("Enter the depth, please: "); depth=fromTheKb3.nextDouble(); } double getVolume() { return width*height*depth; } } tMyn
package Timosoft; import java.util.Scanner; import java.util.Locale; public class MatchBox extends Box { double weight; MatchBox() { super(); System.out.println("MatchBox constructor called."); setWeight(); } tMyn
void setWeight() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb4=new Scanner(System.in); System.out.print("Enter the weight, please: "); weight=fromTheKb4.nextDouble(); } double getWeight() { return weight; } } tMyn
package Timosoft; public class BoxTest { public static void main(String[] args) { Box first=new Box(); System.out.println("The volume of the Box object is "+ first.getVolume()); MatchBox second=new MatchBox(); System.out.println("The weight of the MatchBox object is "+ second.getWeight()); System.out.println("The volume of the MatchBox object is "+ second.getVolume()); } } tMyn
Box constructor called. Enter the width, please: 1.23 Enter the height, please: 4.56 Enter the depth, please: 7.89 The volume of the Box object is 44.253432 Box constructor called. Enter the width, please: 0.12 Enter the height, please: 3.45 Enter the depth, please: 6.78 MatchBox constructor called. Enter the weight, please: 9.01 The weight of the MatchBox object is 9.01 The volume of the MatchBox object is 2.80692 BUILD SUCCESSFUL (total time: 1 minute 7 seconds) tMyn
From the preceding example: • From the class Box we have derived a MatchBox class: public class MatchBox extends Box • The extends keyword identifies that Box is a base class for MatchBox, so an object of type MatchBox will have members that are inherited from the Box class, in addition to the members of the MatchBox class that appear in its definition. tMyn
The constructor for the base class constructs the base class portion of the object (so when creating an object to the base class that is all there is), and the constructor for the derived class constructs the derived class part. • This makes sense because the base class has no knowledge of or access to any element in a derived class. • Thus, their construction must be separate. Each class does have its own constructors, derived class does not inherit the base class constructors. • Constructors are not inherited, but the constructor of the base class can be invoked from the derived class. tMyn
You should always call an appropriate base class constructor from the constructors in your derived class. • The base class constructor call must be the first statement in the body of the derived class constructor. • If the code does not include an explicit call to the base class constructor, Java implicitly calls the base class’s default or no-argument constructor. • The base class constructor call syntax is keyword super followed by a set of parentheses () containing the base class constructor arguments. • When a base class contains a no-argument constructor, you can use super() to call that constructor explicitly, but that is not a must. tMyn
Let us modify the previous example: now there are constructors with parameters in both the base class and the derived class. • Any form of constructor defined by the base class can be called by super(). • The constructor executed will be the one that matches the arguments: tMyn
package TimoSoft; import java.util.Scanner; import java.util.Locale; public class Box { double width, height, depth; Box() { System.out.println("Box default constructor called."); setWidth(); setHeight(); setDepth(); } Box(double wVal, double hVal, double dVal) { System.out.println("Box constructor with 3 params. called."); setWidth(wVal); setHeight(hVal); setDepth(dVal); } tMyn
void setWidth() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb1=new Scanner(System.in); System.out.print("Enter the width, please: "); width=fromTheKb1.nextDouble(); } void setHeight() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb2=new Scanner(System.in); System.out.print("Enter the height, please: "); height=fromTheKb2.nextDouble(); } void setDepth() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb3=new Scanner(System.in); System.out.print("Enter the depth, please: "); depth=fromTheKb3.nextDouble(); } tMyn
void setWidth(double w) { width=w; } void setHeight(double h) { height=h; } void setDepth(double d) { depth=d; } double getVolume() { return width*height*depth; } } tMyn
package TimoSoft; import java.util.Scanner; import java.util.Locale; public class MatchBox extends Box { double weight; MatchBox() { super(); System.out.println("MatchBox default constructor called."); setWeight(); } MatchBox(double weVal) { super(); System.out.println("MatchBox constructor with 1 param. called."); setWeight(weVal); } tMyn
MatchBox(double wiVal, double heVal, double deVal) { super(wiVal, heVal, deVal); System.out.println("MatchBox constructor with 3 param. called."); setWeight(); } MatchBox(double wiVal, double heVal, double deVal, double weVal) { super(wiVal, heVal, deVal); System.out.println("MatchBox constructor with 4 param. called."); setWeight(weVal); } void setWeight() { Locale.setDefault(Locale.ENGLISH); Scanner fromTheKb4=new Scanner(System.in); System.out.print("Enter the weight, please: "); weight=fromTheKb4.nextDouble(); } tMyn
void setWeight(double w) { weight=w; } double getWeight() { return weight; } } tMyn
package TimoSoft; public class Test { public static void main(String[] args) { MatchBox third=new MatchBox(9.74); System.out.println("The weight of the MatchBox object third is "+ third.getWeight()); System.out.println("The volume of the MatchBox object third is "+ third.getVolume()); MatchBox fourth=new MatchBox(10.2, 20.4, 30.6); System.out.println("The weight of the MatchBox object fourth is "+ fourth.getWeight()); System.out.println("The volume of the MatchBox object fourth is "+ fourth.getVolume()); tMyn
MatchBox fifth=new MatchBox(1.23, 4.56, 7.89, 0.12); System.out.println("The weight of the MatchBox object fifth is "+ fifth.getWeight()); System.out.println("The volume of the MatchBox object fifth is "+ fifth.getVolume()); } } tMyn
run: Box default constructor called. Enter the width, please: 6.6 Enter the height, please: 8.8 Enter the depth, please: 9.9 MatchBox constructor with 1 param. called. The weight of the MatchBox object third is 9.74 The volume of the MatchBox object third is 574.992 Box constructor with 3 params. called. MatchBox constructor with 3 param. called. Enter the weight, please: 14.4 The weight of the MatchBox object fourth is 14.4 The volume of the MatchBox object fourth is 6367.248 Box constructor with 3 params. called. MatchBox constructor with 4 param. called. The weight of the MatchBox object fifth is 0.12 The volume of the MatchBox object fifth is 44.253432 BUILD SUCCESSFUL (total time: 56 seconds) tMyn
As could be seen, constructors are called in order of derivation, from base class to derived class (when a derived class object was created). • Further, since super() must be the first statement executed in a derived class’ constructor, this order is the same whether or not super() is used explicitly. • If super() is not used, then the default (parameterless) constructor of each base class will be executed. tMyn
When a derived class calls super(), it is calling the constructor of its immediate base class. • Thus, super() always refers to the base class immediately above the calling class. This is true even in a multilevel hierarchy. • There is a second form of super that acts somewhat like this, except that it always refers to the base class of the derived class in which it is used. • This usage has the following general form: super.member tMyn
Here, member can be either a method or an instance variable. • This form of super is most applicable to situations in which member names of a derived class hide members by the same name in the base class. tMyn
As stated earlier, the default access setting (in which no access specifier is used) is the same as public unless your program is broken down into packages. • The primary purpose of public methods is to present to the class’s clients a view of the services the class provides (the class’s public interface). • Clients of the class need not be concerned with how the class accomplishes its tasks. • For this reason, the private instance variables and private methods of a class (i.e., the class’s implementation details) are not directly accessible to the class’s clients. tMyn
The next example (class definitions are extremely simple ones) demonstrates the public keyword usage, and the behavior is exactly the same as what it would be without this keyword. • There is two level class hierarchy, and first an object is created to the base class: tMyn
package TimoSoft; public class A { public int a; public A(int aVal) { System.out.println("A constructor called."); setA(aVal); } public void setA(int aValue) { a=aValue; } public int getA() { return a; } } tMyn
package TimoSoft; public class B extends A { public int b; public B(int aVal, int bVal) { super(aVal); System.out.println("B constructor called."); setB(bVal); } public void setB(int bValue) { b=bValue; } tMyn
public int getB() { return b; } public void getInfo() { System.out.println("The instance variable values a and b are: "+ a+" and "+b+"."); } } tMyn
package TimoSoft; public class Test { public static void main(String[] args) { A first=new A(1); System.out.println("The instance variable value, "+ "object first, a: "+first.getA()); first.a=2; System.out.println("The instance variable value, "+ "object first, a: "+first.getA()); first.setA(3); System.out.println("The instance variable value, "+ "object first, a: "+first.getA()); } } tMyn
run: A constructor called. The instance variable value, object first, a: 1 The instance variable value, object first, a: 2 The instance variable value, object first, a: 3 BUILD SUCCESSFUL (total time: 0 seconds) tMyn
As a second step an object is created to the derived class: tMyn
public class Test { public static void main(String[] args) { B first=new B(1, 2); System.out.println("The instance variable values, object first, a and b: "+ first.getA()+" and "+first.getB()+"."); first.getInfo(); first.a=3; first.b=4; first.getInfo(); } } tMyn
A constructor called. B constructor called. The instance variable values, object first, a and b: 1 and 2. The instance variable values a and b are: 1 and 2. The instance variable values a and b are: 3 and 4. BUILD SUCCESSFUL (total time: 0 seconds) tMyn
From the preceding example: using keyword public means that “everything” is possible! • When a member of a class is modified by the public access specifier, that member can be accessed by any other code in your program wherever the program has a reference to an object of that class or one of its derived classes. • A small modification to the previous example: base class instance variable access modifier is changed to private: tMyn
package TimoSoft; public class A { private int a; public A(int aVal) { System.out.println("A constructor called."); setA(aVal); } public void setA(int aValue) { a=aValue; } public int getA() { return a; } } tMyn