360 likes | 450 Views
MIT AITI 2003 – Lecture 12. Inheritance. What is Inheritance?.
E N D
MIT AITI 2003 – Lecture 12 Inheritance
What is Inheritance? • Real World Example: We inherit traits from our mother and father. We also inherit traits from our grandmother, grandfather, and ancestors. We might have similar eyes, the same smile, a different height….but we are essentially “derived” from our parents. • In Software, object inheritance is more well defined! Object types that are derived from other object types “resemble” their parent classes by inheriting/copying both state/variables and behavior/methods.
Picture Representation Both variables and methods are inherited String name void eat() FOOD String name void eat() int juiceLevel inherited FRUIT String name int juiceLevel void eat() void slice() APPLE inherited
Inheritance • All Java classes inherit implicitly from Object • Classes that inherit from other classes can call methods from those classes, and can access their data members and methods (except for those that are private) • Inheritance is useful because it allows you to reuse functionality and to manage complexity
Inheritance Example Object class A { int x; } class B extends A { int y; } class C extends B { int z; } A B C
x x y y z Inheritance Example x Instance of A has just A's fields. Its type is A (and Object). Instance of B has fields from A and B. Its type is A and B (and Object). Instance of C has fields from A, B and C. Its type is A, B and C (and Object).
Inheritance Example static public void main(String[] args) { A aa = new A(); A ab = new B(); /* a B is also an A */ A ac = new C(); /* a C is also an A */ B bb = new B(); B bc = new C(); C cc = new C(); /* not legal -> an A is not a B! */ // B ba = new A(); /* compile error */ }
Advantages of Inheritance • Complex classes and data types are already provided in java packages / libraries. We want to reuse these classes, and modify to our requirements: java.io input/ouput operations java.swing GUI components java.awt.geom 2D geometric objects java.applet Applets embedded in web pages java.util Data Structures – collection classes (Set, List,Tree, Vector) java.sql Supports Database access • Also – we want to write very abstract classes and then specialize (abstract classes). Example: We write an abstract shape class, and then keep on adding new shapes (next lecture).
Type Hierarchy Object-oriented systems allow classes to be defined in terms of other classes. For example, a square, triangle, and circle are all shapes. In object-oriented terminology, a square/triangle/circle are subclasses of the shape class. Similarly, the shape class is the superclass of all shape objects. Shape objects are also Objects. Object Class/Type Hierarchy Inherit State and Behavior Specialize Point Shape Pixel Circle Triangle Square
We wrote a Point class. Now we want a ColorPoint class or a GraphicsPixelPoint class. We can just use existing variables/methods in the Point class (inherit these) and then write more code to add new functionality (extend the base class). We simply add a color field to our Point, or other graphics information for a pixel point. We can use 2D geometry package classes already in java.awt.geom, and extend these classes to have specialized behavior. (Don’t need to reinvent Line, Circle, Rectangle classes.) Reusing Classes
public class ColorPoint { private Point point; private Color color; // We wrap a color field around a Point object. public ColorPoint(Point p, Color color) { point = p; this.color = color; } } DELEGATION Less Elegant Way of “reuse”
public class ColorPoint extends Point { private Color color; public ColorPoint(double x, double y, Color color) { super(x, y); // Make into a Point first. this.color = color; // Add info for new ColorPoint. } } INHERITANCE Extending the Point Class/Type
Constructors… Example I public class Shape { Shape() { System.out.println(“I am a Shape”); } } public class RoundShape extends Shape { RoundShape() { System.out.println(“I am a Round Shape”); } } public class Circle extends RoundShape { Circle() { System.out.println(“I am a Circle”); } public static void main(String[] args) { Circle x = new Circle(); } }
I am a Shape I am a Round Shape I am a Circle Default Constructors for superclasses called. When we construct a Circle, we are first making it a Shape, then a RoundShape, and finally a Circle. Output of Program
Constructor Example II class Plant { private String kingdom; private String genus; private String species; private boolean poisonous; public Plant(String g, String s, boolean p) { kingdom= "Plantae"; genus= g; species= s; poisonous= p; } } We write a base Plant class. All Plants are kingdom Plantae. Specific objects of the Plant type have a genus and species.
continued… class Tree extends Plant { private double crownSize; private double trunkSize; public Tree(String g, String s, double cs, double ts) { super(g, s, false); crownSize= cs; trunkSize= ts; } } An object of Type Tree is also a Plant. Hence, it is of kingdom Plantae. We first call the super class constructor to make our object a Plant. Then we add crownSize and trunkSize modifications to make our object a Tree.
Hiding fields class SuperClass { int inheritData; double data; } class SubClass extends SuperClass { float data; } SubClass inherits inheritData. However, data is defined twice. In SubClass, we now have two data fields (one hidden) float data is newly defined. super.data can also be accessed in subclass.
Overriding Methods class SuperClass { … boolean isTrue() { } int totalSum(int x, int y) { } } class SubClass extends SuperClass { … // OVERRIDE totalSum method above, and add something. int totalSum(int x, int y) { super.totalSum(x, y); // Can Call Superclass method. // Do something more now, MODIFY System.out.println(“I can now add modifications.”); } }
Access: Private,Public,Protected,no access specified (package) • Super Class may contain members (methods or data) of type: • Private: • Know About This: Access only internally in class. • Protected (a little unsafe, tricky, so avoided) • Access: • To Methods of all Subclasses. • To all Classes in same package • Package (no access specified) • Access by methods of classes in same package • Public: • Know about this: Access to all classes everywhere.
Final and Static • In SuperClass, can define a variable or method as final and static: • Static: If subclass has access, then it will inherit the static variable or static method and it will be shared between all objects of a derived class AND base class. • Final: If a variable, method, or class is defined as FINAL, then it cannot be overriden in a subclass.
Casting Objects From the inheritance concept, we now also can CAST objects into different types. OBJECT POINT COLORPOINT // Don’t need Cast if assigning a superclass type. Point p = new Point(4.4, 5.6); Object pHolder = (Object)p; Object pHolder = p; // Could just write this statement. // Need Casting if assigning a subclass type. Object x = new Point(3.0, 4.4); Point xPoint = (Point) x;
When Casting is Needed OBJECT POINT COLORPOINT In general, don’t need to cast unless we need methods of the subclass type. Object o = new ColorPoint(4.4, 3.4, new Color(“red”)); Can use: o.toString() and will get appropriate method. Can’t use: o.getX() since o has object type, not point. So cast to use getX() method.
Continued… OBJECT POINT COLORPOINT Object o = new ColorPoint(4.4, 3.4, new Color(“red”)); Can’t use: o.getX(); Using Casting to Point: Now Can Use: ( ( Point ) o ).getX(); OR can use ColorPoint cast to use very specific methods: ((ColorPoint) o).getColor();
Casting Example Vector v = new Vector(); v.addElement(new Rectangle(…..)); v.addElement(new Square(……)); v.addElement(new Circle(……)); for (int k = 0; k < v.size(); k++) { v.elementAt(k).toString(); ((v.elementAt(k)) Shape).draw(); // Cast needed }
Casting - Summary In general casting is not encouraged – becomes too confusing. A programmer should design superclasses properly so we don’t need to call specific methods all the time. But, many advantages (previous Vector exercise): We can draw all types of different shapes just by using a general draw method. We don’t have to call each rectangle, circle, square draw method separately.
Programming Example • A Company has a list of Employees. It asks you to provide a payroll sheet for all employees. • Has extensive data (name, department, pay amount, …) for all employees. • Different types of employees – manager, engineer, software engineer. • You have an old Employee class but need to add very different data and methods for managers and engineers. • Suppose someone wrote a name system, and already provided a legacy Employee class. The old Employee class had a printData() method for each Employee that only printed the name. We want to reuse it, and print pay info. Borrowed with permission from Course 1.00 Notes
REVIEW PICTURE Message passing “Main event loop” Encapsulation Employee e1 public … Main(…){ Employeee1…(“Mary”,“Wang”); ... e1.printData(); // Prints Employee names. ... } printData private: lastName firstName
Employee class class Employee { // Data private String firstName, lastName; // Constructor public Employee(String fName, String lName) { firstName= fName; lastName= lName; } // Method public void printData() { System.out.println(firstName + " " + lastName);} } This is a simple super or base class.
Inheritance Already written: Class Employee firstName lastName printData() is-a is-a Class Engineer hoursWorked wages Class Manager salary firstName lastName firstName lastName printData() getPay() printData() getPay() You next write:
Engineer class Subclass or (directly) derived class Class Engineer extends Employee { private double wage; private double hoursWorked; public Employee(String fName, String lName, double rate, double hours) { super(fName, lName); wage = rate; hoursWorked = hours; } public double getPay() { return wage * hoursWorked; } public void printData() { super.printData(); // PRINT NAME System.out.println("Weekly pay: $" + Wage* hoursWorked); } }
Manager class Subclass or (directly) derived class class Manager extends Employee { private double salary; public Manager(String fName, String lName, double sal){ super(fName, lName); salary = sal; } public double getPay() { return salary; } public void printData() { super.printData(); System.out.println("Monthly salary: $“ + salary);} }
Inheritance… Class Manager Salary firstName lastName is-a printData getPay Class SalesManager firstName lastName Salary printData getPay salesBonus
SalesManager Class class SalesManager extends Manager { private double bonus; // Bonus Possible as commission. // A SalesManager gets a constant salary of $1250.0 public SalesManager(String fName, String lName, double b) { super(fName, lName, 1250.0); bonus = b; } public double getPay() { return 1250.0; } public void printData() { super.printData(); System.out.println(“Bonus Pay: $" + bonus; } } Derived class from derived class
Main method public class PayRoll { public static void main(String[] args) { // Could get Data from tables in a Database. Engineer fred = new Engineer(“Fred", "Smith", 12.0, 8.0); Manager ann = new Manager("Ann", "Brown", 1500.0); SalesManager mary= new SalesManager("Mary", “Kate", 2000.0); // Polymorphism, or late binding Employee[] employees = new Employee[3]; employees[0]= fred; employees[1]= ann; employees[2]= mary; for (int i=0; i < 3; i++) employees[i].printData(); } } Java knows the object type and chooses the appropriate method at run time
Output from main method Fred Smith Weekly pay: $96.0 Ann Brown Monthly salary: $1500.0 Mary Barrett Monthly salary: $1250.0 Bonus: $2000.0 Note that we could not write: employees[i].getPay(); because getPay() is not a method of the superclass Employee. In contrast, printData() is a method of Student, so Java can find the appropriate version.