// CS U213 Spring 2007 // Lecture 10: January 31, 2007 /* We will continue working on our Company example form Monday. To reming you here is the class diagram from last time. +-----------+ | Emp |<-----------------------------+ +-----------+ | | | | +-----------+ | | | | | /_\ | | | +-----------------------------------+ | | | | +----------------+ +------------------+ | | Worker | | Boss | | +----------------+ +------------------+ | |String name | | String name | | |int tasks | | String unit | | +----------------+ | int tasks | | +--------+ ListofEmp peons | | | +------------------+ | | | v | +--------------+ | | ListofEmp |<------------------------+--+ +--------------+ | | +--------------+ | | | | | | | | /_\ | | | | | +--------------------------------+ | | v v | | +-----------------+ +-------------------+ | | | MTListofEmp | | ConsListofEmp | | | +-----------------+ +-------------------+ | | +-----------------+ | Emp first +---+ | | ListofEmp rest +------+ +-------------------+ Today we will address the following questions (a) How many levels of subordination does a Boss have? (b) Get the list of subordinates for a Boss. Let's look at (a). Where do we start? Which class should we look at first and why? We should start with Boss. The question asks for the levels of subordination. The only class that has subordinates is Boss. Boss is the class that has the information to asnwer this question. So in class Boss ---------------- // to count the levels of subordination under this Boss. int countLevels() { ... } Examples (using instances we created on monday) ----------------------------------------------- ann.countLevels() => 2 dave.countLevels() => 3 mike.countLevels() => 1 Template --------- int countLevels() { ... this.peons ... //ListofEmp ... this.peons.maxDepth() // int } We delegate to the method maxDepth() in ListofEmp. The list's maximum depth of the list, is the level of subordinations for the Boss. So now we need to add the methd maxDepth() to ListofEmp. In ListofEmp ------------ // count the maximum depth of subordinates in this list int maxDepth(); Examples --------- ann.peons.maxDepth() => 4 pete.peons.maxDepth() => 2 empty.peons.maxDepth() => 0 We need to add the method maxDepth to the classes that implement ListofEmp. In MTListofEmp ------------- // count the maximum depth of subordinates in this list int maxDepth() { return 0; } In ConsListofEmp ---------------- // count the maximum depth of subordinates in this list int maxDepth() { ... this.first ... // Emp ... this.rest ... // ListofEmp ... this.rest.maxDepth() ... // int } We want to obtain the maximum depth. But that might be the value returned from the recursive call to this.rest.maxDepth() OR the level of subordinates that this.first has. Let's make some examples to make this clear. Examples -------- (D) implies the list with only worker D. (D).maxDepth() => 1 mike.maxDepth() => 2 meg.maxDepth() => 5 dave.maxDepth() => 4 This means that we need a method maxDepth() in Emp that will calculate the maximum levels of subordinates in an Emp AND a method "max" that returns the maximum of 2 numbers. In Emp ------ // to count the maximum depth of subordinates in this Emp int maxDepth(); In Worker --------- // to count the maximum depth of subordinates in this Worker int maxDepth() { return 1; } In Boss --------- // to count the maximum depth of subordinates in this Boss int maxDepth() { return 1+ this.countLevels(); } In ConsListofEmp ---------------- // return the maximum between a and b int max(int a, int b) { if (a>b) return a; else return b; } Now, let's go back and write the body of the method maxDepth in ConsListofEmp. In ConsListofEmp ---------------- // count the maximum depth of subordinates in this list int maxDepth() { return max(this.first.maxDepth(), this.rest.maxDepth()) ; } */ interface Emp { // count all Employees int countAll(); // count subordinates int countSubs(); // to count the maximum depth of subordinates in this Emp int maxDepth(); } class Worker implements Emp { String name; int tasks; Worker(String name, int tasks){ this.name = name; this.tasks = tasks; } // count all Employees int countAll() { return 1; } // count subordinates int countSubs() { return 0; } // to count the maximum depth of subordinates in this Worker int maxDepth() { return 1; } } class Boss implements Emp { String name; String unit; int tasks; ListofEmp peons; Boss(String name, String unit, int tasks, ListofEmp peons){ this.name = name; this.unit = unit; this.tasks = tasks; this.peons = peons; } // count all subordinates int countSubs(){ return this.peons.countAll(); } // count all Employees int countAll(){ return 1 + this.countSubs(); } // to count the maximum depth of subordinates in this Boss int maxDepth() { return 1+ this.countLevels(); } // to count the levels of subordination under this Boss. int countLevels() { return this.peons.maxDepth(); } } interface ListofEmp { // count all employees in the list int countAll(); // count the maximum depth of subordinates in this list int maxDepth(); } class MTListofEmp implements ListofEmp { MTListofEmp() {} // count all employees in the list int countAll(){ return 0; } // count the maximum depth of subordinates in this list int maxDepth() { return 0; } } class ConsListofEmp implements ListofEmp { Emp first; ListofEmp rest; ConsListofEmp(Emp first, ListofEmp rest){ this.first = first; this.rest = rest; } // count all employees in the list int countAll() { return this.first.countAll() + this.rest.countAll(); } // return the maximum between a and b int max(int a, int b) { if (a>b) return a; else return b; } // count the maximum depth of subordinates in this list int maxDepth() { return this.max(this.first.maxDepth(), this.rest.maxDepth()) ; } } class Examples { Examples() {} Emp wkA = new Worker("A",3); Emp wkB = new Worker("B",5); Emp wkC = new Worker("C",6); Emp wkD = new Worker("D",4); Emp wkE = new Worker("E",5); Emp wkF = new Worker("F",2); Emp wkG = new Worker("G",8); Emp wkH = new Worker("H",6); ListofEmp mtlist = new MTListofEmp(); ListofEmp grpAlist = new ConsListofEmp(this.wkC,this.mtlist); Emp mike = new Boss("Mike", "Group A", 10, this.grpAlist); ListofEmp secAlist = new ConsListofEmp(this.mike, new ConsListofEmp(this.wkD, new ConsListofEmp(this.wkE,this.mtlist))); Emp jack = new Boss("Mike", "Section A", 25, this.secAlist); ListofEmp secBlist = new ConsListofEmp(this.wkF, new ConsListofEmp(this.wkG, this.mtlist)); Emp jenn = new Boss("Jenn", "Section B", 15, this.secBlist); ListofEmp secClist = new ConsListofEmp(this.wkH,this.mtlist); Emp pat = new Boss("Pat", "Section C", 20, this.secClist); ListofEmp secDlist = new ConsListofEmp(this.wkB, this.mtlist); Emp pete = new Boss("Pete", "Section D", 10, this.secDlist); ListofEmp operList = new ConsListofEmp(this.jack, new ConsListofEmp(this.jenn, new ConsListofEmp(this.pat, this.mtlist))); Emp dave = new Boss("Dave","Operations", 70, this.operList); ListofEmp financeList = new ConsListofEmp(this.pete, new ConsListofEmp(this.wkA, this.mtlist)); Emp anne = new Boss("Anne", "Finance", 20, this.financeList); ListofEmp ceoList = new ConsListofEmp(this.dave, new ConsListofEmp(this.anne,this.mtlist)); Emp meg = new Boss("Meg","CEO", 100, this.ceoList); boolean test1 = check this.anne.countSubs() expect 3; boolean test2 = check this.dave.countSubs() expect 10; boolean t1 = check this.secAlist.countAll() expect 4; boolean t2 = check this.mtlist.countAll() expect 0; boolean t3 = check this.financeList.countAll() expect 3; // Only the Boss class has countLevels! Boss anneBoss = new Boss("Anne", "Finance", 20, this.financeList); Boss daveBoss = new Boss("Dave","Operations", 70, this.operList); Boss mikeBoss = new Boss("Mike", "Group A", 10, this.grpAlist); Boss peteBoss = new Boss("Pete", "Section D", 10, this.secDlist); boolean t4 = check this.anneBoss.countLevels() expect 2; boolean t5 = check this.daveBoss.countLevels() expect 3; boolean t6 = check this.mikeBoss.countLevels() expect 1; boolean t7 = check this.anneBoss.peons.maxDepth() expect 2; boolean t8 = check this.peteBoss.peons.maxDepth() expect 1 ; boolean t9 = check this.mtlist.maxDepth() expect 0; boolean t10 = check this.daveBoss.maxDepth() expect 4; boolean t11 = check this.mike.maxDepth() expect 2; boolean t12 = check this.meg.maxDepth() expect 5; boolean t13 = check this.dave.maxDepth() expect 4; }