Dog size int energy int set Size set

  • Slides: 24
Download presentation
Dog - size : int - energy : int + set. Size() + set.

Dog - size : int - energy : int + set. Size() + set. Energy() + equals(Object) : boolean + hash. Code() : int + to. String() : String. . . Mix - breeds : Array. List<String> + equals(Object) : boolean + hash. Code() : int + to. String() : String. . . 1

why is the constructor call to the superclass needed? because Mix is-a Dog and

why is the constructor call to the superclass needed? because Mix is-a Dog and the Dog part of Mix needs to be constructed a derived class can only call its own constructors or the constructors of its immediate superclass Mix can call Mix constructors or Dog constructors Mix cannot call the Object constructor Mix cannot call Pure. Breed constructors cannot call constructors across the inheritance hierarchy Pure. Breed cannot call Komondor constructors 2 Object is not the immediate superclass of Mix cannot call subclass constructors

Constructors & Overridable Methods if a class is intended to be extended then its

Constructors & Overridable Methods if a class is intended to be extended then its constructor must not call an overridable method Java does not enforce this guideline why? 3 recall that a derived class object has inside of it an object of the superclass object is always constructed first, then the subclass constructor completes construction of the subclass object the superclass constructor will call the overridden version of the method (the subclass version) even though the subclass object has not yet been constructed

Superclass Ctor & Overridable Method public class Super. Duper { public Super. Duper() {

Superclass Ctor & Overridable Method public class Super. Duper { public Super. Duper() { // call to an over-ridable method; bad this. override. Me(); } public void override. Me() { System. out. println("Super. Duper override. Me"); } } 4

Subclass Overrides Method public class Subby. Dubby extends Super. Duper { private final Date

Subclass Overrides Method public class Subby. Dubby extends Super. Duper { private final Date date; public Subby. Dubby() { super(); this. date = new Date(); } @Override public void override. Me() { System. out. print("Subby. Dubby override. Me : "); System. out. println( this. date ); } public static void main(String[] args) { Subby. Dubby sub = new Subby. Dubby(); sub. override. Me(); } 5 }

the programmer's intent was probably to have the program print: Super. Duper override. Me

the programmer's intent was probably to have the program print: Super. Duper override. Me Subby. Dubby override. Me : <the date> or, if the call to the overridden method was intentional Subby. Dubby override. Me : <the date> but the program prints: Subby. Dubby override. Me : null Subby. Dubby override. Me : <the date> 6 final attribute in two different states!

What's Going On? 1. 2. 3. 4. 5. 6. 7 new Subby. Dubby() calls

What's Going On? 1. 2. 3. 4. 5. 6. 7 new Subby. Dubby() calls the Subby. Dubby constructor calls the Super. Duper constructor calls the method override. Me which is overridden by Subby. Dubby the Subby. Dubby version of override. Me prints the Subby. Dubby date attribute which has not yet been assigned to by the Subby. Dubby constructor (so date is null) the Subby. Dubby constructor assigns date Subby. Dubby override. Me is called by the client

remember to make sure that your base class constructors only call final methods or

remember to make sure that your base class constructors only call final methods or private methods 8 if a base class constructor calls an overridden method, the method will run in an unconstructed derived class

a derived class can only call its own constructors or the constructors of its

a derived class can only call its own constructors or the constructors of its immediate superclass Mix can call Mix constructors or Dog constructors Mix cannot call the Object constructor Mix cannot call Pure. Breed constructors cannot call constructors across the inheritance hierarchy Pure. Breed cannot call Komondor constructors 9 Object is not the immediate superclass of Mix cannot call subclass constructors

Other Methods methods in a subclass will often need or want to call methods

Other Methods methods in a subclass will often need or want to call methods in the immediate superclass a new method in the subclass can call any public or protected method in the superclass without using any special syntax a subclass can override a public or protected method in the superclass by declaring a method that has the same signature as the one in the superclass 10 a subclass method that overrides a superclass method can call the overridden superclass method using the super keyword

Dog equals we will assume that two Dogs are equal if their size and

Dog equals we will assume that two Dogs are equal if their size and energy are the same @Override public boolean equals(Object obj) { boolean eq = false; if(obj != null && this. get. Class() == obj. get. Class()) { Dog other = (Dog) obj; eq = this. get. Size() == other. get. Size() && this. get. Energy() == other. get. Energy(); } return eq; } 11

Mix equals (version 1) two Mix instances are equal if their Dog subobjects are

Mix equals (version 1) two Mix instances are equal if their Dog subobjects are equal and they have the same breeds @Override public boolean equals(Object obj) { // the hard way boolean eq = false; if(obj != null && this. get. Class() == obj. get. Class()) { Mix other = (Mix) obj; subclass can call public method of this. get. Energy() == other. get. Energy() && the superclass this. breeds. size() == other. breeds. size() && eq = this. get. Size() == other. get. Size() && this. breeds. contains. All(other. breeds); } return eq; } 12

Mix equals (version 2) two Mix instances are equal if their Dog subobjects are

Mix equals (version 2) two Mix instances are equal if their Dog subobjects are equal and they have the same breeds Dog equals already tests if two Dog instances are equal Mix equals can call Dog equals to test if the Dog subobjects are equal, and then test if the breeds are equal also notice that Dog equals already checks that the Object argument is not null and that the classes are the same 13 Mix equals does not have to do these checks again

@Override public boolean equals(Object obj) { subclass method that overrides a superclass boolean eq

@Override public boolean equals(Object obj) { subclass method that overrides a superclass boolean eq = false; method can call the overridden superclass method if(super. equals(obj)) { // the Dog subobjects are equal Mix other = (Mix) obj; eq = this. breeds. size() == other. breeds. size() && this. breeds. contains. All(other. breeds); } return eq; } 14

Dog to. String @Override public String to. String() { String s = "size "

Dog to. String @Override public String to. String() { String s = "size " + this. get. Size() + "energy " + this. get. Energy(); return s; } 15

Mix to. String @Override public String to. String() { String. Buffer b = new

Mix to. String @Override public String to. String() { String. Buffer b = new String. Buffer(); b. append(super. to. String()); for(String s : this. breeds) b. append(" " + s); b. append(" mix"); return b. to. String(); } 16

Dog hash. Code // similar to code generated by Eclipse @Override public int hash.

Dog hash. Code // similar to code generated by Eclipse @Override public int hash. Code() { final int prime = 31; int result = 1; result = prime * result + this. get. Energy(); result = prime * result + this. get. Size(); return result; } 17

Mix hash. Code // similar to code generated by Eclipse @Override public int hash.

Mix hash. Code // similar to code generated by Eclipse @Override public int hash. Code() { final int prime = 31; int result = super. hash. Code(); result = prime * result + this. breeds. hash. Code(); return result; } 18

Mix Memory Diagram • inherited from superclass • private in superclass • not accessible

Mix Memory Diagram • inherited from superclass • private in superclass • not accessible by name to Mix 500 Mix object size 5 energy 5 breeds 1750 19

Mix UML Diagram Dog 1 Array. List<String> Mix breeds 20

Mix UML Diagram Dog 1 Array. List<String> Mix breeds 20

Preconditions and Inheritance precondition inheritance (is-a) what the method assumes to be true about

Preconditions and Inheritance precondition inheritance (is-a) what the method assumes to be true about the arguments passed to it a subclass is supposed to be able to do everything its superclasses can do how do they interact? 21

Strength of a Precondition to strengthen a precondition means to make the precondition more

Strength of a Precondition to strengthen a precondition means to make the precondition more restrictive // Dog set. Energy weakest precondition // 1. no precondition // 2. 1 <= energy // 3. 1 <= energy <= 10 strongest precondition public void set. Energy(int energy) {. . . } 22

Preconditions on Overridden Methods a subclass can change a precondition on a method but

Preconditions on Overridden Methods a subclass can change a precondition on a method but it must not strengthen the precondition 23 a subclass that strengthens a precondition is saying that it cannot do everything its superclass can do // Dog set. Energy // assume non-final // @pre. none // Mix set. Energy // bad : strengthen precond. // @pre. 1 <= nrg <= 10 public void set. Energy(int nrg) { //. . . } public void set. Energy(int nrg) { if (nrg < 1 || nrg > 10) { // throws exception } //. . . }

 client code written for Dogs now fails when given a Mix // client

client code written for Dogs now fails when given a Mix // client code that sets a Dog's energy to zero public void walk(Dog d) { d. set. Energy(0); } remember: a subclass must be able to do everything its ancestor classes can do; otherwise, clients will be (unpleasantly) surprised 24