1 / 79

Inheritance

Inheritance. Inheritance is a fundamental object-oriented technique that supports reuse of software. In this lecture: Inheritance Polymorphism, widening & narrowing Method overriding protected and final modifiers A word about multiple inheritance. Inheritance.

rressler
Télécharger la présentation

Inheritance

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inheritance • Inheritance is a fundamental object-oriented technique that supports reuse of software. • In this lecture: • Inheritance • Polymorphism, widening & narrowing • Method overriding • protected and final modifiers • A word about multiple inheritance

  2. Inheritance • Inheritance allows us to derive a new class from an existing one • The existing class is called the superclass or base-class. • derived class is called the subclass or derived-class. • Instances of the derived class inherit all the properties and functionality that is defined in the base class. • Usually, the derived class adds more functionality and properties.

  3. Example setTime() getSeconds()getMinutes() getHours() secondElapsed() ... Clock AlarmClock AnalogClock getSecondsPointerAngle()getMinutesPointerAngle() getHoursPointerAngle() setAlarm() setAlarmState()

  4. The is a relationship • Inheritance creates an is-a relationship. AnalogClockis aClock, AlarmClockis a Clock. • Everything that can be done with a Clock object can also be done with an AlarmClock object. • An AnalogClock is a special kind of Clock. It has all the functionality of a clock and some more. • The subclass instances are more specific than the instances of the superclass.

  5. Example moveForwards(float size) turnLeft(float teta)turnRight(float teta) tailUp() ... Turtle drawPolygon(int n, float size) drawSquare(int n) IntelligentTurtle

  6. /** * A logo turtle that knows how to draw composite * figures such as polygons. */ public class IntelligentTurtle extends Turtle { /** * Draws a perfect polygon. * @param n The number of edges * @param edgeSize The size of each edge */ public void drawPolygon(int n, float edgeSize) { float teta = 360.0f / n; for (int i=0; i<n; i++) { moveForwards(edgeSize); turnLeft(teta); } } } The extends Keyword

  7. // Draws a perfect polygon whose number of edges is // given by the user and the size of is edge is fixed class PerfectPolygon { static final float EDGE_SIZE = 100.0f; /** * Draws a perfect polygon. */ public static void main(String[] args) { int n = Integer.parseInt(args[0]); IntelligentTurtle painter = new IntelligentTurtle(); painter.tailDown(); painter.drawPolygon(n, EDGE_SIZE); } } Example

  8. When to derive a subclass? • Derived class should normally extend the functionality of the superclass • In certain cases, a derived class would change some of the functionality of the superclass • Thumb Rule: Subclass only when it is reasonable from the point of view of the abstractions!

  9. Point Employee TextField Pixel Manager PasswordField Examples Frame Dialog FileDialog

  10. What is Inherited? • When you derive a class from a given base class: • The subclass inherits all the fields of the base class • It inherits all the methods of the base class • You have to declare the constructors of the subclass from scratch • Private fields and methods are inherited but cannot be accessed directly from the code of the subclass

  11. Switch Example Switch • Switch() • boolean isOn() • setOn(boolean) • isOn

  12. /** * An electronic switch that can be on/off. */ public class Switch { // Records the state of the switch private boolean isOn; /** * Checks if this switch is on. * @return true if the switch is on. */ public boolean isOn() { return isOn; } /** * Sets the state of the switch on/off. */ public void setOn(boolean state) { isOn = state; } } Switch Code

  13. on off Switch vs. Adjustable Switch an adjustable switch has a “level of current” dial pressing the adjustable switch turns it on

  14. Inheriting AdjustableSwitch from Switch • Switch() • isOn() • setOn(boolean) Switch • AdjustableSwitch() • setLevel(float) • getLevel() AdjustableSwitch

  15. AdjustableSwitch Code /** * An adjustable electronic switch. */ public class AdjustableSwitch extends Switch { // The level of current (0-100) private float level; // . . . getLevel() and setLevel() }

  16. AdjustableSwitch Code (cont.) /** * Sets the level of current * @param level the required level of current(0%-100%) */ public void setLevel(float level) { if (level < 0.0f || level > 100.0f) { throw new IllegalArgumentException(); } this.level = level; } /** * Returns the level of current of the switch. */ public float getLevel() { return level; }

  17. AdjustableSwitch Example AdjustableSwitch • setOn(boolean) • isOn() • AdjustableSwitch() • setLevel(float) • getLevel() • isOn • level

  18. Private Fields - Inherited but not Accessible • Notice that an AdjustableSwitch object has a state variable isOn • This variable is inherited from Switch • However, it cannot be accessed directly from the code of AdjustableSwitch because it is defined as private in Switch - i.e., it is encapsulated

  19. Inheritance: a Basis for Code Reusability • Fast implementation - we need not write the implementation of AdjustableSwitch from scratch, we just implement the additional functionality. • Ease of use - If someone is already familiar with the base class, then the derived class will be easy to understand. • Less debugging - debugging is restricted to the additional functionality. • Ease of maintenance - if we need to correct/improve the implementation of Switch, AdjustableSwitch is automatically corrected as well. • Compactness - our code is more compact and is easier to understand.

  20. Example: Changing the Base Class • Suppose that we want to add the property of ‘maximal power’ to our representation of a switch. • This property is suitable in adjustable switches as well (the inheritance supports our abstraction!). • Inheritance allows us to add this property only in the base class. The changes will automatically take place in the inherited class.

  21. Changing the Switch Class /** * An electronic switch that can be on/off. */ public class Switch { // Records the state of the switch private boolean isOn; // The maximal power of this switch private float maxPower;

  22. Changing the Switch Class /** * Constructs a new switch. * @param power the maximal power of the switch. */ public Switch(float maxPower) { if (maxPower <= 0.0f) { throw new IllegalArgumentException(); } this.maxPower = maxPower; } /** * Returns the maximal power of this switch. */ public float getMaxPower() { return maxPower; }

  23. Constructors Must Be Redefined! • Note that the constructor of Switch receives a parameter - maxPower - and initializes the private field with the same name. • We have to define a constructor for AdjustableSwitch that receives the same parameter and initializes this field. But this field is private, so there is no direct access to it. • In general, when we invoke a constructor of a subclass, we first have to construct the superclass “part” of the subclass. We do this by using the super keyword.

  24. /** * Constructs an adjustable switch. * @param power the maximal power of the switch. * @exception IllegalArgumentException if the power * is negative. */ public AdjustableSwitch(float power) { super(power); } AdjustableSwitch - Redefinition of Constructor The first line of the constructor calls the constructor of the superclass (Switch) that receives a float parameter to initialize the state variable defined in the superclass

  25. Calling super(...) • The constructor of a derived class MUST initialize the state of the object from the point of view of its parent class. Thus the first line in the constructor must be a call to one of the constructors in the superclass using super(...). You cannot make a later call to super(...) because to can invoke a constructor only once! • If you do not call super(...) in the first line of the constructor, the compiler automatically places a call to the empty constructor of the superclass. • If there is no empty constructor in the superclassthe code will not compile!

  26. Automatic Default Construction • In the previous implementation of Switch and AdjustableSwitch we didn’t include any constructors. • The compiler automatically added an empty (default) constructor to each of the classes. • In addition, the compiler had put in the first line of the empty constructor of Switch a call to the empty constructor of AdjustableSwitch.

  27. Automatic Default Construction // ...in class Switch (automatically added) public Switch() { } // and in class AdjustableSwitch (automatically added) public AdjustableSwitch() { super(); }

  28. Default Construction Using Other Constructors • Sometimes the programmer may wish to define a default constructor by herself, which calls other constructors with default arguments of her choice

  29. Default Construction - Delegation private static final DEFAULT_POWER = 60.0f; /** * Constructs a new switch. * @param power the maximal power of the switch. */ public Switch(float maxPower) { if (maxPower <= 0.0f) { throw new IllegalArgumentException(); } this.maxPower = maxPower; } /** * Constructs a switch with default power. */ public Switch() { this(DEFAULT_POWER); }

  30. Overriding • In certain case, when we derive a class, we want to change some of the functionality defined in the superclass. • Example: We want clients to be able to open a protected file only if it is unlocked • File() • isOpen() • open() • close() File • RestrictedFile(long key) • isLocked() • lock() • unlock(long key) RestrictedFile

  31. File Example /** * Part of a File implementation */ public class File { // true if the file is opened private boolean isOpen; /** * Checks if the file is open. * @return true iff the file is open */ public boolean isOpen() { return isOpen; } // other methods/variables... }

  32. File Example /** * Opens the file. */ public void open() { // … other operations isOpen = true; } /** * Closes the file. */ public void close() { // … other operations isOpen = false; } }

  33. RestrictedFile Example /** * Represents a restricted file, which can be opened * only if it is unlocked. In order to unlock * the file a key is needed. */ public class RestrictedFile extends File { // Password for unlocking the file private long key; // The state of the file - locked/unlocked private boolean isLocked; /** * Constructs a new restricted file. * @param key The key to unlock the file */ public RestrictedFile(long key) { this.key = key; isLocked = true; }

  34. RestrictedFile Example /** * Checks if the file is locked. */ public boolean isLocked() { return isLocked; } /** * Locks the file. */ public void lock() { isLocked = true; }

  35. RestrictedFile Example /** * Unlock the file. The file will be unlocked only * if the given key matches. * @param key the key to unlock the file */ public void unlock(long key) { if (this.key == key) { isLocked = false; } else // ... } So far the implementation is useless if we do not change the implementation of open()

  36. RestrictedFile Example /** * Open the file. The file will be opened only if it * is unlocked. */ public void open() { if (!isLocked()) { super.open(); } else // ... }

  37. Overriding in RestrictedFile • RestrictedFile inherits the interface of File, but changes the functionality of the method open(). • We say that RestrictedFileoverrides the method open(). • Notice the call to super.open() - we invoke the method open() of the superclass on this object.

  38. Rules of Overriding • When you derive a class B from a class A, the interface of class B will be a superset of that of class A (except for constructors) • You cannot remove a method from the interface by subclassing (explain why...) • However, class B can override some of the methods that it inherits and thus change their functionality. • The contract of a method states what is expected from an overriding implementation of the method.

  39. The Object Class • Java defines the class java.lang.Object that is defined as a superclass for all classes. • If a class doesn’t specify explicitly which class it is derived from, then it will be implicitly derived from class Object. • So, in the previous example, RestrictedFile was derived from File which in turn was derived from Object. • We can depict the relationship between this classes in the following diagram, that is called class hierarchy diagram.

  40. Hierarchy Diagram Object File RestrictedFile

  41. The Object Class • The Object class defines a set of methods that are inherited by all classes. • One of these is the toString() method that is used whenever we want to get a String representation of an object. • When you define a new class, you can override the toString() method in order to have a suitable representation of the new type of objects as Strings. • The contract of the toString() method says that you are expected to return a String that represents your object

  42. Point: Example of Overriding toString() /** * Represents a point on a grid. */ public class Point { // The coordinates of the point private int x,y; /** * Constructs a new point. * @param x,y The coordinates of the point. */ public Point(int x, int y) { this.x = x; this.y = y; } public String toString() { return “Point: (“ + x + ”,” + y + ”)”; }

  43. Point: Example of Overriding toString() // Example of overriding the toString() method class PrintingPointExample { public static void main(String[] args) { Point p = new Point(2,3); System.out.println(p); //System.out.println(p.toString()); } } The output of the program will be: Point: (2,3)

  44. Polymorphism • Recall the is-a relationship induced by inheritance: A RestrictedFileis aFile which is anObject. • We can view a RestrictedFile object from 3 different points of views: • As a RestrictedFile. This is the most narrow point of view (the most specific). This point of view ‘sees’ the full functionality of the object. • As a File. This is a wider point of view (a less specific one). We forget about the special characteristics the object has as a RestrictedFile (we can only open and close the file). • As an plain Object.

  45. Polymorphism • We view an object by using an object reference. • A variable of type ‘reference to File’ can only refer to an object which is aFile. File f = new File(); • But a RestrictedFile is also a File, so f can also refer to a RestrictedFile object. File f = new RestrictedFile(); • The type of the reference we use determines the point of view we will have on the object.

  46. Polymorphism • If we refer to a RestrictedFile object using a RestrictedFile reference we have the RestrictedFile point of view - we see all the methods that are defined in RestrictedFile and up the hierarchy tree. • RestrictedFile f = new RestrictedFile(12345); • f.close(); • f.lock(); • f.unlock(12345); • String s = f.toString();

  47. Polymorphism • If we refer to a RestrictedFile object using a File reference we have the File point of view - which lets us use only methods that are defined in class File and up the hierarchy tree. • File f = new RestrictedFile(12345); • f.close(); • f.lock(); • f.unlock(12345); • String s = f.toString();

  48. Polymorphism • If we refer to a RestrictedFile object using an Object reference we have the Object point of view - which let us see only methods that are defined in class Object. • Object f = new RestrictedFile(12345); • f.close(); • f.lock(); • f.unlock(12345); • String s = f.toString();

  49. Polymorphism RestrictedFile • toString() • ... • isOpen() • open() • close() • lock() • unlock(key) • isLocked() • ... • isOpen • isLocked • key

  50. Widening • Changing our point of view of an object, to a wider one (a less specific one) is called widening. File myFile; myFile = new RestrictedFile(12345); RestrictedFile referenceRestrictedFile point of view File referenceFile point of view Widening

More Related