// CS U213 Spring 2007 // Lecture 4: January 17, 2007 //Designing unions with containment: Self reference //------------------------------------------------- //Lets try to define an ancestor tree(a tree representing information about one's ancestors) /* ;;In Scheme ;;--------- ;;An Ancestor Tree (AT) is one of ;; -- empty ;; --(make-tree String String AT AT) (define-struct tree (name eye-color mother father)) ;;Examples: ;;--------- (make-tree "Carlos" "brown" empty empty) */ //In Java //------- //Unions are defined in Java using interface! /* +----+ | AT |<-----------------+ +----+ | +----+ | | | / \ | --- | | | ------------------- | | | | +-------+ +------------------+ | | Empty | | Tree | | +-------+ +------------------+ | +-------+ | String name | | | String eyecolor | | | AT mother |-+ | | AT father |-+ | +------------------+ | | | | +--+ */ //Note: Containment arrows, pointing to the interface class, indicate self-reference! //The class diagram translates to the following Java code. // represents an ancestor tree interface AT { } // represents lack of ancestor information class Empty implements AT { Empty() { } } // represents ancestor information class Tree implements AT { String name; String eyecolor; AT mother; AT father; Tree(String name, String eyecolor, AT mother, AT father) { this.name = name; this.eyecolor = eyecolor; this.mother = mother; this.father = father; } } //Examples: //--------- /* class Examples{ Examples() {} AT empty=new Empty(); AT margaret=new Tree("Margaret","green",this.empty,this.empty); AT peter=new Tree("Peter","blue",this.margaret,this.empty); } */ //------------------------------------------------------------------------------// //Lets try to define a river //A RiverPart is one of: // --source:location(Point) // --confluence:location(Point) left(RiverPart) right(RiverPart) // A River is :location(Point) flow(RiverPart) /* +-----------+ +--------------->| RiverPart |<-----------------+ | +-----------+ | | +-----------+ | | | | | / \ | | --- | | | | | ------------------------ | | | | | | +----------------+ +-----------------+ | | | Source | | Confluence | | | +----------------+ +-----------------+ | | | Point location |--+-| Point location | | | +----------------+ | | RiverPart left |-+ | | | | RiverPart right |-+ | | | +-----------------+ | | | | | | | | +--+ | | | | | +----------------+ | | | River | | | +----------------+ | | | Point location |---+ +-| RiverPart flow | | +----------------+ | | | +-------------+ | | Point |<--+ +-------------+ | int x | | int y | | String name | +-------------+ */ // represents a cartesian point class Point { int x; int y; String name; Point(int x, int y, String name) { this.x = x; this.y = y; this.name = name; } } // represents a part of a river interface RiverPart { } // represents the source of a river class Source implements RiverPart { Point location; Source(Point location) { this.location = location; } } // represents the confluence of two parts of a river class Confluence implements RiverPart { Point location; RiverPart left; RiverPart right; Confluence(Point location, RiverPart left, RiverPart right) { this.location = location; this.left = left; this.right = right; } } // represents a river class River { Point location; RiverPart flow; River(Point location, RiverPart flow) { this.location = location; this.flow = flow; } } //Examples: //--------- class Examples{ Examples() {} RiverPart c=new Source(new Point(10,10,"c")); RiverPart d=new Source(new Point(20,10,"d")); RiverPart b=new Confluence(new Point(20,20,"b"),this.c,this.d); River a=new River(new Point(30,30,"a"),this.b); }