isa versus hasa Inheritance allows us to specialize

  • Slides: 17
Download presentation
is_a versus has_a • Inheritance allows us to specialize a particular class. Assume we

is_a versus has_a • Inheritance allows us to specialize a particular class. Assume we have a class called Fruit, then we could subclass Fruit and create an Apple class. This new subclass Apple is a special type of Fruit. • We say “Apple is_a Fruit” • This type of relationship is called an is_a relationship. • More examples: – – Fall 2002 Automobile is a special case of transportation vehicle. Shirt is a particular kind of clothing. Bald eagle is a species of bird. Triangle is a type of polygon. COP 3330 Object Oriented Programming 1

is_a versus has_a • Not all relationships between classes are is_a relationships. • Sometimes

is_a versus has_a • Not all relationships between classes are is_a relationships. • Sometimes we have has_a relationships (also called contains_a relationships). • We’ve already talked about has_a relationships! We called it composition (also called aggregation). • Assume we have a Triangle class. Triangles are made up of vertices. We “compose” a Triangle class of Vertex (supplier) classes. • We say “Triangle has_a Vertex” • More examples: – An automobile contains a steering wheel. – A shirt contains a pocket. – A bald eagle has a wing. Fall 2002 COP 3330 Object Oriented Programming 2

is_a versus has_a • Inheritance (is_a) and composition (has_a) both provide ways to reuse

is_a versus has_a • Inheritance (is_a) and composition (has_a) both provide ways to reuse software. • In inheritance, we can reuse the superclass. • In composition, we can reuse the supplier class. • Typically, inheritance should be used only when a clear is_a relationship exists. Fall 2002 COP 3330 Object Oriented Programming 3

Example – Vectors and Stacks • A Vector in Java is essentially an array

Example – Vectors and Stacks • A Vector in Java is essentially an array that grows in size dynamically. • A stack is a data structure that allows items to be put in/taken out in a certain way. (It is not random access like a Vector). • However, the designers of the Java API decided to create a Stack class by making it a subclass of a Vector. • This is poor design; it allows users of the Stack class access to the methods of the Vector class (since those methods were inherited). • However, the Vector methods allow random access! This means users of the Stack class can access items in ways that are not consistent with a stack’s operation. Fall 2002 COP 3330 Object Oriented Programming 4

Inheritance and References • The data type of a variable can be: – a

Inheritance and References • The data type of a variable can be: – a primitive data type, or – a reference type (which will hold a reference to an object). • So, a variable of reference type holds a reference to an object. class C 1 {. . . } // in some other place C 1 x; • What can be the class of the object which is referred by the variable x? • A variable of reference type can refer to an object of its declared class, or to an object of any subclass of its declared class. – This means that x can store a reference to an object of C 1 or an object of any subclass of C 1 (its siblings). Fall 2002 COP 3330 Object Oriented Programming 5

Inheritance and References (cont. ) • Another way of saying it: A variable declared

Inheritance and References (cont. ) • Another way of saying it: A variable declared to be of a superclass type can be bound to an object of the same superclass type or any object of a subclass type. • Yet another way: An instance of a subclass can appear wherever an instance of its superclass is expected. Fall 2002 COP 3330 Object Oriented Programming 6

Inheritance and References (cont. ) class C 1 {. . . } class C

Inheritance and References (cont. ) class C 1 {. . . } class C 2 extends C 1 {. . . } class C 3 {. . . } // in some other place C 1 o 1 = new C 1(); C 2 o 2 = new C 2(); C 3 o 3 = new C 3(); o 1 = o 2; Automatically saved (Widening Conversion) o 2 = (C 2) o 1; We need explicit type casting (Narrowing Conversion) if o 1 holds C 2 object, this is okay; But, if o 1 holds C 1 object run-time error o 1 = o 3; o 1 = (C 1) o 3; Fall 2002 ILLEGAL (There is no inheritance relation between C 1 and C 3) COP 3330 Object Oriented Programming 7

Inheritance and References (cont. ) • Assigning a descendant reference to an ancestor reference

Inheritance and References (cont. ) • Assigning a descendant reference to an ancestor reference is considered to be a widening conversion, and it can be performed by simple assignment. • Assigning an ancestor reference to a descendant reference is considered to be a narrowing conversion, and it must be done with an explicit type cast operation. – If that ancestor reference does not point to a descendant object run-time error • Since Object class is the ancestor of all classes in Java, we can store any type of reference in an Object reference variable. Fall 2002 COP 3330 Object Oriented Programming 8

Inheritance and References (cont. ) class C 1 {. . . } class C

Inheritance and References (cont. ) class C 1 {. . . } class C 2 extends C 1 {. . . } // in some other place C 1 o 1 = new C 1(); C 2 o 2 = new C 2(); Object o 3; o 1 = o 2; o 2 = (C 2) o 1; Conversion) Automatically saved (Widening Conversion) We need explicit type casting (Narrowing This is okay, because o 1 holds an C 2 object. o 3 = o 1; Automatically saved (Widening Conversion) o 3 = o 2; Automatically saved (Widening Conversion) Fall 2002 COP 3330 Object Oriented Programming 9

Inheritance and References (cont. ) • So, a variable of reference type holds a

Inheritance and References (cont. ) • So, a variable of reference type holds a reference to an object. • A variable of reference type may hold references to objects of different classes. • The class of the object referred to by a reference variable cannot always be determined at compile time. it can be determined only at run time. • We can say that any class is a subclass (or subtype) of an ancestor class. The subtype relationship does not have to be direct. Assume Fruit extends Object. Apple extends Fruit. Granny. Smith. Apple extends Apple. • Then we can say that Fruit is a subtype of Object, Apple is a subtype of Object, Granny. Smith. Apple is a subtype of Fruit, etc. Fall 2002 COP 3330 Object Oriented Programming 10

Conversion of Types • There is a difference between conversions of primitive types and

Conversion of Types • There is a difference between conversions of primitive types and reference types: – During the conversion of a primitive type, the representation of the value being converted is changed. – The conversion of an object reference does not affect the representation of the object. The identity of object and state remain the same. Fall 2002 COP 3330 Object Oriented Programming 11

Subtype Polymorphism Subtype polymorphism – the ability of a single variable to refer to

Subtype Polymorphism Subtype polymorphism – the ability of a single variable to refer to objects of differing type Rule of Assignment: The type of the expression on the right-side of an assignment must be the same type as or a subtype of the variable on the left-hand side of the assignment. class Student {. . . } class Undergraduate extends Student {. . . } class Graduate extends Student {. . . } Student student 1, student 2; student 1 = new Undergraduate(); student 2 = new Graduate(); Fall 2002 COP 3330 Object Oriented Programming // polymorphic assignment 12

Polymorphism (cont. ) Graduate student 3; Although student 2 holds a Graduate object, the

Polymorphism (cont. ) Graduate student 3; Although student 2 holds a Graduate object, the following statement will be illegal. student 3 = student 2; compilation error But, the following will be okay: student 3 = (Graduate) student 2; student 3 = (Graduate) student 1; runtime error because student 1 holds an Undergraduate object. Fall 2002 COP 3330 Object Oriented Programming 13

Downcasting • Casting a variable to a subtype of its declared type is called

Downcasting • Casting a variable to a subtype of its declared type is called downcasting. • For example, explicit type casting of the variable student 2 whose declared type is Student is downcasting. Graduate student 3; student 3 = (Graduate) student 2; • Java allows explicit type casting of any reference type T 1 to any reference type T 2 which holds a subclass relation with T 1 at compile time. • The validity of an explicit type casting is always checked at run time. If the cast is invalid, a Class. Cast. Exception will be thrown. • In our example, a run-time check will be performed to determine whether student 2 holds a reference to an object that is an instance of Graduate or its subclasses. If it is not, a Class. Cast. Exception will be thrown. Fall 2002 COP 3330 Object Oriented Programming 14

Proper Ways of Downcasting • Use instanceof operator before downcasting: expression instanceof Type returns

Proper Ways of Downcasting • Use instanceof operator before downcasting: expression instanceof Type returns true if expression is an instance of Type (or its subtype). if (student 1 instanceof Graduate) { Graduate grad. Student = (Graduate) student 1; . . . } else { // student 1 is not a graduate student. . . } Fall 2002 COP 3330 Object Oriented Programming 15

Proper Ways of Downcasting (cont. ) • Catch Class. Cast. Exception exception: try {

Proper Ways of Downcasting (cont. ) • Catch Class. Cast. Exception exception: try { Graduate grad. Student = (Graduate) student 1; . . . } catch (Class. Cast. Exception e) { // student 1 is not a graduate student. . . } Fall 2002 COP 3330 Object Oriented Programming 16

Is Downcasting Needed? • If Graduate class defines a method get. Research. Topic() and

Is Downcasting Needed? • If Graduate class defines a method get. Research. Topic() and this method is not defined in Student class, the following code will give a compilation error (although s 1 holds a Graduate object). Student s 1 = new Graduate(); s 1. get. Research. Topic(); compilation error. • So, we have to downcast s 1 to Graduate, before we invoke the method. Student s 1 = new Graduate(); Graduate gs = (Graduate) s 1; gs. get. Research. Topic(); Fall 2002 COP 3330 Object Oriented Programming 17