290 likes | 374 Views
Inheritance. Like father like son. Image from: http://www.latimes.com/includes/ramirez/ramirez_20031125.gif. Inheritance. Sometimes classes have commonalities Consider a checking/savings/ cd account Consider a janitor/sales clerk/manager
E N D
Inheritance Like father like son Image from: http://www.latimes.com/includes/ramirez/ramirez_20031125.gif
Inheritance • Sometimes classes have commonalities • Consider a checking/savings/cd account • Consider a janitor/sales clerk/manager • Inheritance is a way of writing common code once, and using it in many classes • Commonalities are captured in a super-class • Also known as a base class or parent class • Differences are captured in sub-classes • Also known as a child class Image from: http://www.glenbard.net/Glenbard_East/Activities/media/GIFs/Businessman%20yelling%20into%20b.gif
Inheritance • Software reuse is at the heart of inheritance • The sub-class class inherits all properties of the parent • all methods • all variables • Inheritance relationships can be depicted in a UML class diagram • boxes represent classes • lines represent relationships between classes • an arrow with an open arrowhead pointing to the parent class indicates inheritance
Vehicle Car Motorcycle Inheritance Inheritance creates an is-a relationship The child is a more specific kindof the parent class Vehicle { // data and methods } class Car extends Vehicle { // more data and methods } class Motorcycle extends Vehicle { // more data and methods } UML Diagram indicating inheritance Java code indicating inheritance
Inheritance • Syntax: public class SubClassextendsSuperClass { // data and methods } • Read “SubClass is a specialized version of SuperClass” • All Oval’s have width and height • Circle is a specialized oval since the width and height are always the same.
Business RetailBusiness ServiceBusiness WebBased MaAndPa HomeBasedService Class Hierarchies • A child class of one parent can be the parent of another child, forming a class hierarchy
The super Reference • Constructors are NOT inherited • A child’s constructor is responsible for calling the parent’s constructor • The word super • can be used as a method to mean “the parent classes constructor” • can be used as a direct reference to the super class • The first line of a child’s constructor should use the super reference to call the parent’s constructor
The super Reference class Account { protected double balance; Account(double openingBalance) { balance = openingBalance; } } class MoneyMarketAccount extends Account { protected double annualInterestRate; MoneyMarketAccount(double openingBalance, double rate) { balance = openingBalance; // could you do this annualInterestRate = rate; // could you do this? } } image from http://www.gamasutra.com/features/designers_notebook/superman.gif
The super Reference class Account { protected double balance; Account(double openingBalance) { balance = openingBalance; } } class MoneyMarketAccount extends Account { protected double annualInterestRate; MoneyMarketAccount(double openingBalance, double rate) { super(openingBalance); // should do this annualInterestRate = rate; // should do this } } image from http://www.menzies.us/ img/superman.gif
Example import java.awt.Color; public class RedDot extends Oval { public RedDot( int x, int y, int d ) { super(x, y, d, d); setBackground( Color.red ); } public void flatten() { setSize(getWidth()+1, getHeight()-1); repaint(); } } // assume a Jframe named window RedDot dotty = new RedDot(10, 20, 5); window.add(dotty,0); dotty.repaint(); dotty.setLocation(20, 30); dotty.flatten();
Conformance • When performing assignment “x = y;” • Y must conform to X • If X and Y are primitives then the type of y must • be the identical to the type of X • OR widen to the type of X • Otherwise • The class of Y must be identical to the class of X • OR the class of Y must be a subclass of X
Overriding Methods • A method in a super-class can be overridden in a sub-class. • The sub-class method must have exactly the same signature • same access, return type, name, formal parameter list • The sub-classes method is able to re-define the behavior of the super-class method http://gladstone.uoregon.edu/~edetzler/n.w.riding/images/fly.gif
Overriding Oval s1 = new Oval(x,y,w,h); … s1.setSize(30, 30); Target t1 = new Oval(x,y,w,h); … t1.setSize(30, 30);
Dynamic Dispatch • Mechanism used to determine which method to actually call • Determined at run time • The class of the actual calling object is determined • If that class contains the specified method, then execute it, otherwise look in the super-class for the method. Repeat if needed!
class A { int i, j; A(int a, int b) { i = a; j = b; } 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; } void show() { System.out.println(“k: “ + k); } } class Example { public static void main(String[] args) { B aBThing = new B(1,2,3); aBThing.show(); } } OverridingExample 1
Consider public void foo(A jubJub) { jubJub.jabberwock(); } … foo(new A()); // OK? foo(new B()); // OK? foo(new C()); // OK? foo(new D()); // OK? Compile time: an object is treated as it’s declared type. Compiler ensures that the runtime code will work – not what the runtime code exactly means! Runtime: an object is treated according to it’s actual (most specific) type!
class A { public void foo() { System.out.println(“inside foo A”); } } class B extends A { public void foo() { System.out.println(“inside foo B”); } } class C extends B { public void foo() { System.out.println(“inside foo C”); } } class Demo { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); A reference; reference = a; reference.foo(); reference = b; reference.foo(); reference = c; reference.foo(); } } OverridingExample 2
BasicCheckbook # balance : int «constructor» + BasicCheckbook( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + balanceInCents() : int public class BasicCheckbook { protected int balance; // in cents /* postcondition balance == bd*100 + bc */ public BasicCheckbook(int bd, int bc) { balance = bd*100 + bc; } /* postcondition balance == old balance + dd*100 + dc */ public void deposit(int dd, int dc) { balance = balance + dd*100 + dc; } /* postcondition balance == old balance - (wd*100 + wc) */ public void withdraw(int wd, int wc) { balance = balance - (wd*100 + wc); } /* postcondition result == balance */ public int balanceInCents() { return balance; } } Image from: http://www.southernunited.com/sufi_images/page1/checkbook.jpg
BasicCheckbook # balance : int «constructor» + BasicCheckbook( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int balanceInCents() CheckbookWithStrBalance «constructor» + CheckbookWithStr...( int, int) «query» + String toString() public class CheckbookWithStrBalance extends BasicCheckbook { public CheckbookWithStrBalance(int bd, int bc) { super(bd, bc); } public String toString() { String dollarStr, centStr; int cents; dollarStr = "" + (balance / 100); cents = balance % 100; if (cents < 10) { centStr = "0" + cents; } else { centStr = "" + cents; } return "$" + dollarStr + "." + centStr; } }
BasicCheckbook # int balance «constructor» + BasicCheckbook( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int balanceInCents() CheckbookWithTotals # int depositTot # int withdrawTot «constructor» + CheckbookWithTotals( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int deposits() + int withdraws() CheckbookWithStrBalance «constructor» + CheckbookWith...( int, int) «query» + String toString() public class CheckbookWithTotals extends CheckbookWithStrBalance { protected int depositTot, withdrawTot; public CheckbookWithTotals(int bd, int bc) { super(bd, bc); depositTot = 0; withdrawTot = 0; } public void deposit(int dd, int dc) { super.deposit(dd, dc); depositTot = depositTot + dd*100 + dc; } public void withdraw(int wd, int wc) { super.withdraw(wd, wc); withdrawTot = withdrawTot - (wd*100 + wc); } public int deposits() { return depositTot; } public int withdraws() { return withdrawTot; } }
Permit overdraft (negative balance) (charge $10 for each transaction in the red)
BasicCheckbook # int balance «constructor» + BasicCheckbook( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int balanceInCents() CheckbookWithTotals # int depositTot # int withdrawTot «constructor» + CheckbookWithTotals( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int deposits() + int withdraws() CheckbookWithStrBalance «constructor» + CheckbookWith...( int, int) «query» + String toString() public class CheckbookWithRedInk extends CheckbookWithTotals { public CheckbookWithRedInk(int bd, int bc) { super(bd, bc); } public void deposit(int dd, int dc) { super.deposit(dd, dc); if (dd*100+dc < 0 && balance < 0) { System.out.println("$10 surcharge"); balance = balance - 1000; } } public void withdraw(int wd, int wc) { super.withdraw(wd.wc); if (wd*100+wc > 0 && balance < 0) { System.out.println("$10 surcharge"); balance = balance - 1000; } } public String toString() { String str; if (balance > 0) { str = super.toString(); } else { balance = -balance; str = "(" + super.toString() + ")"; balance = -balance; } return str; } }
CheckbookWithRedInk # int balance # int depositTot # int withdrawTot «constructor» + CheckbookWithRedInk( int, int) «update» + deposit( int, int) + withdraw( int, int) «query» + int balanceInCents() + String toString() + int deposits() + int withdraws() A flattened version of the class A client public class Director { private CheckbookWithRedInk checkbook; public Director() { checkbook = new CheckbookWithRedInk( 100, 0 ); checkbook.deposit( 20, 0 ); checkbook.withdraw( 125, 99 ); System.out.println("Final Balance: " + checkbook.toString()); } }
Container • This class is meant to be extended to create customized components • Probably want to overridesetSize for example • Probably don’t need to overridegetX, getY, setLocation, getWidth, getHeight • Example: write a TrafficLight class! • Lights are centered horizontally and distributed vertically • Lights are 3/4 of the width of the light and ¼ of the light height
Object • All classes descend from Object • Two methods that should often be overridden boolean equals(Object other) : returns true if the calling object is equal to the other one and false otherwise String toString() : returns the textual representation of the calling object
Fraction Class • Write a Fraction class • Represents a fraction (i.e. numerator / denominator) • Support addition and multiplication • Support equality checking and conversion to text // Code fragment showing usage Fraction f1 = new Fraction(3,5); Fraction f2 = new Fraction(6,3); Fraction f3 = f1.add(f2); Fraction f4 = f1.multiply(f2); System.out.println(f4.toString()); System.out.println(f4.equals(f3));
Fraction class • What does a Fraction object look like textually? • When are two Fraction objects the same? public class Fraction { private int num, denom; public Fraction(int n, int d) { … } public Fraction() { … } public Fraction multiply(Fraction other) { … } public Fraction add(Fraction other) { … } public String toString() { …} public boolean equals(Object other) { … } }
Equality • Equality can be defined in two ways • Identity equality: two objects are equal iff they are the same object • Content equality: two objects are equal if they have the same content • Both definitions are supported in Java • ==: this operator always means identity equality. Can be applied to objects. • equals method: this method usually means content equality but is defined as identity equality by default. Fraction f1 = new Fraction(3,5); Fraction f2 = new Fraction(3,5); Fraction f3 = new Fraction(5,3); boolean b1 = f1 == f2; boolean b2 = f1 == f3; boolean b3 = f1.equals(f2); boolean b4 = f1.equals(f3);
Summary • Most classes should override toString and equals • The equals method allows a class to define what equality means • The toString method allows a class to define it’s textual look.