intro to cs – honors i inheritance and polymorphism georgios portokalidis [email protected]

30
Intro to CS – Honors I Inheritance and Polymorphism GEORGIOS PORTOKALIDIS [email protected]

Upload: doreen-warner

Post on 16-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Intro to CS – Honors IInheritance and PolymorphismGEORGIOS PORTOKALIDIS

[email protected]

Inheritance

Generic class

More specializedclasses

Even more Specialized classes

Why Inheritance? You can define or use a generic class

Later, you can define a more a specialized class that inherits the properties of the generic class

Persons in StevensWhat kind of properties

are shared by all persons?What kind of properties are shared by students?

public class Person{

private String name;public Person(){

name = "No name yet";}public Person(String initialName){

name = initialName;}public void setName(String newName){

name = newName;}public String getName(){

return name;}public void writeOutput(){

System.out.println("Name: " + name);}public boolean hasSameName(Person otherPerson){

return this.name.equalsIgnoreCase(otherPerson.name);}

}

Students in Stevens All students are persons

All students have a student number

We want a class that inherits all properties of a person but includes a student number

The class Student inherits all public methods and attributes of Person

◦ It can add its own instance variables and methods

public class Student extends Person{

private int studentNumber;

public int getStudentNumber(){

return studentNumber;}public void setStudentNumber(int

newStudentNumber){

studentNumber = newStudentNumber;}

}Can I access Person’s name? Private is private!

Using Derived Classes

public class InheritanceDemo{

public static void main(String[] args){

Student s = new Student();

s.setName("Warren Peace")s.setStudentNumber(1234);

}}

Which constructor is called?

This method is inherited

This method is only defined in Student

The default constructor of Student, which in turn by default invokes the default constructor of its base class

When to Use Inheritance If an is-a relationship does not exist between two proposed classes, do not use inheritance to derive one class from the other

It could be a has-a relationship◦ Define an object of one class as an instance variable within the other class

SYNTAXpublic class Derived_Class_Name extends Base_Class_Name{

Declarations_of_Added_Instance_VariablesDefinitions_of_Added__And_Changed_Methods

}

Using Derived Classes

public class InheritanceDemo{

public static void main(String[] args){

Student s = new Student();

s.setName("Warren Peace")s.setStudentNumber(1234);s.writeOutput();

}}

Invokes method of Person

Name: Warren Peace

Overridingpublic class Student extends Person{

…public void writeOutput() {

System.out.println("Name: " + getName());System.out.println("Student Number: " +

studentNumber);}

}

You can define a new method with the same heading which overrides the inherited one

Using Derived Classes

public class InheritanceDemo{

public static void main(String[] args){

Student s = new Student();

s.setName("Warren Peace")s.setStudentNumber(1234);s.writeOutput();

}}

Name: Warren PeaceStudent Number: 1234

Overriding is not Overloading

public class Person{

private String name;…public String getName(){

return name;}

}

public class Student extends Person{

…public String getName(String

title) {

return title + getName();

}}

public class Student extends Person{

…public char[] getName(String

title) {

return title + getName();

}}

Cannot override with the same signature and

different return type

Preventing Overridingpublic class Person{

private String name;…public final String

getName(){

return name;}

}

Final methods cannot be overriden

public final class Person{

private String name;…public final String

getName(){

return name;}

}

Final classes cannot be extended

UML Inheritance Diagrams

How About Constructorspublic class Student extends Person{

private int studentNumber;

public Student(){

name = "No name yet";studentNumber = 0;

}public Student(String initialName, int

initialNumber){

setName(initialName);studentNumber = InitialNumber;

}}

What’s bad with this?

public class Student extends Person{

private int studentNumber;

public Student(){

super();studentNumber = 0;

}public Student(String initialName, int

initialNumber){

super(initialName);studentNumber = InitialNumber;

}}

Call the constructor of the parent/base class

super() behaves as this(). Must be the first action in

the constructor Call the constructor of the parent/base class

How About Constructorspublic class Student extends Person{

private int studentNumber;

public Student(){

studentNumber = 0;}public Student(String initialName, int

initialNumber){

studentNumber = InitialNumber;

}}

The default constructor is always called if super() is missing

What is the value of an object’s instance variables after using these

constructors?

Use super to Refer to the Base Class

public class Student extends Person{

…public void writeOutput() {

System.out.println("Name: " + super.getName());System.out.println("Student Number: " +

studentNumber);}

}

Use super to Call Overridden Methods

public class Student extends Person{

…public void writeOutput() {

System.out.println("Name: " + super.getName());super.writeOutput();

}}

Beware of Overriding vs Overloading

public class Person{

private String name;

public void reset(String newName) {

name = newName;}

}

public class Student extends Person{

private int studentNumber;

public void reset(String newName, int newNumber)

{setname(newName);name = newName;

}}

Java SE 8 is introducing annotations@Override can be used to force the compiler to produce an error if you are not actually overriding a method

@Override

Multiple Inheritancepublic class Person{

…}

public class Student extends Person{

…}

public class Undergraduate extends Student{

…}

public Undergraduate(){

super.super.writeOutput();}

Not possible

Type Compatibility An Undergrad is a Student is a Person

public class SomeClass{

public static void compareNumbers(Student s1, Student s2){

if (s1.getStudentNumber() == s2.getStudentNumber())

System.out.println(s1.getName() + " has the same " + "number as " + s2.getName());

elseSystem.out.println(s1.getName() + " has a

different“ + "number than " +

s2.getName());}. . .

}

Student studentObject = new Student("Jane Doe", 1234);Undergraduate undergradObject =

new Undergraduate("Jack Buck", 1234, 1);SomeClass.compareNumbers(studentObject, undergradObject);

Type Compatibility Note that this is not automatic type casting

An object can have multiple types◦ An Undergrad is also of the type Student and Person

The reverse is not true◦ A Person is not always a Student◦ Nor a Student always an Undergrad

The Object Class Java has an “Eve” class that is the ancestor of every class

Every class you write implicitly “extends” Object

public class SomeClass extends Object

{

}

You can write methods that take an Object type as parameter that will accept any object◦ Can I pass a primitive type to such methods?

Every class inherits toString() and equals() from Object◦ Do not expect these to work properly

Type Casting to Successor Classes

Example: overriding the defaults equals method

◦ public boolean equals(Object otherObject)

We could declare public boolean equals(Student otherStudent)

What is the problem with this?

To override we need to declare public boolean equals(Object otherObject){

Student otherStudent = (Student)otherObject;return this.hasSameName(otherStudent) &&(this.studentNumber ==

otherStudent.studentNumber);}

Different headings mean we are overloading

Type Casting to Successor Classes

Student oneStudent, otherStudent;

if (oneStudent.equals(otherStudent))

{

}

public boolean equals(Object otherObject){

Student otherStudent = (Student)otherObject;return this.hasSameName(otherStudent) &&(this.studentNumber ==

otherStudent.studentNumber);}

How can this go bad?

String notAStudent;

if (oneStudent.equals(notAStudent))

This will cause a run-time error, since the error cannot be detected at compile time

The instanceof Operatorpublic boolean equals(Object otherObject){

boolean isEqual = false;if ((otherObject != null) &&

(otherObject instanceof Student)){

Student otherStudent = (Student)otherObject;isEqual = this.sameName(otherStudent) &&

(this.studentNumber == otherStudent.studentNumber);}return isEqual;

}

SYNTAXObject instanceof Class_Name

Returns true if the object is of type Class_Name

Multiple Inheritance

ClassA ClassB

ClassC

Object

public class ClassA extends Object {

public void doSomething(){

System.out.println("doSomething implementation of A"); } //ClassA own method public void methodA(){ }

} public class ClassB extends Object {

public void doSomething(){

System.out.println("doSomething implementation of B"); } //ClassB own method public void methodB(){ }

} public class ClassC extends ClassB, ClassA{

public void test(){

doSomething();}

}

Which method will be called?

It is impossible to decide which method to call. Java avoids the diamond problem by

disallowing multiple inheritance

Polymorphism “Polymorphism allows you to make changes in the method definition for the derived classes and have those changes apply to the methods written in the base class.”

Person[] people = new Person[4];

people[0] = new Undergraduate("Cotty, Manny", 4910);people[1] = new Undergraduate("Kick, Anita", 9931);people[2] = new Student("DeBanque, Robin", 8812);people[3] = new Undergraduate("Bugg, June", 9901);

for (Person p: people){

p.writeOutput();System.out.println();

}

Let’s use a for-each loop to print all Persons information

Which writeOutput() will be called?

Even though we are using object references of type Person the methods of the child-class

objects are called

In Java this is called dynamic binding or late binding

Polymorphism REMEMBER Objects Know How They Are Supposed to Act

◦ The method that is to be called is determined at run time, and it does not depend on an the type of an object reference but the actually object

Java always assumes late binding◦ Some other languages allow you to control which methods will use late binding