this keyword BMI Class BMI The get methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. -name: String The name of the person. -age: int The age of the person. -weight: double The weight of the person in pounds. -height: double The height of the person in inches. +BMI(name: String, age: int, weight: double, height: double) Creates a BMI object with the specified name, age, weight, and height. Creates a BMI object with the specified name, weight, height, and a default age 20. +BMI(name: String, weight: double, height: double) +getBMI(): double Returns the BMI +getStatus(): String Returns the BMI status (e.g., normal, overweight, etc.) 2 public class BMI { private String name; private int age; private double weight; // in pounds private double height; // in inches public static final double KILOGRAMS_PER_POUND = 0.45; public static final double METERS_PER_INCH = 0.0254; public BMI(String name, int age, double weight, double height) { this.name = name; this.age = age; this.weight = weight; this.height = height; } this keyword refers to an object itself. One common use of the this keyword is reference a class’s hidden data fields. public BMI(String name, double weight, double height) { this(name, 20, weight, height); } Another common use of the this keyword to enable a constructor to invoke another constructor of the same class. public double getBMI() { double bmi = weight * KILOGRAMS_PER_POUND / ((height * METERS_PER_INCH) * (height * METERS_PER_INCH)); return Math.round(bmi * 100) / 100.0; } public String getStatus() { double bmi = getBMI(); if (bmi < 16) return "seriously underweight"; else if (bmi < 18) return "underweight"; else if (bmi < 24) return "normal weight"; else if (bmi < 29) return "over weight"; else if (bmi < 35) return "seriously over weight"; else return "gravely over weight"; } Abstract Class and Abstract Methods An abstract class is declared with keyword abstract. An abstract class normally contains one or more abstract methods. ABSTRACT CLASSES MAY NOT BE INSTANTIATED using the new operator. public abstract void draw(); // abstract method Abstract methods do not provide implementations. A class that contains any abstract methods must be explicitly declared abstract even if that class contains some concrete methods. Abstract Class and Abstract Methods Each concrete subclass of an abstract superclass also must provide concrete implementations of each of the superclass’s abstract methods. Constructors and static methods cannot be declared abstract. Constructors are not inherited, so an abstract constructor could never be implemented. Though non-private static methods are inherited, they cannot be overridden. Since abstract methods are meant to be overridden so that they can process objects based on their types, it would not make sense to declare a static method as abstract. Software Engineering Observation An abstract class declares common attributes and behaviors (both abstract and concrete) of the various classes in a class hierarchy. An abstract class typically contains one or more abstract methods that subclasses must override if they are to be concrete. The instance variables and concrete methods of an abstract class are subject to the normal rules of inheritance. Q1)Design a class named Triangle that extends GeometricObject. class GeometricObject { ………… } class Triangle extends GeometricObject { ………….. } The class contains: Q2)Three double data fields named side1, side2, and side3 with default values 1.0 to denote three sides of the triangle. class Triangle extends GeometricObject { private double side1 = 1.0, side2 = 1.0, side3 = 1.0; Q3)A no-argument constructor that creates a default triangle. public Triangle() { } Q4) A constructor that creates a triangle with the specified side1, side2, and side3. public Triangle(double side1, double side2, double side3) { this.side1 = side1; this.side2 = side2; this.side3 = side3; } Q5)The accessor methods for all three data fields. // Override abstract getArea() method in GeometricObject public double getArea() { // returns the area of triangle double s = (side1 + side2 + side3) / 2; return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3)); } /*Override abstract getPerimeter () method in GeometricObject*/ public double getPerimeter() { return side1 + side2 + side3; //returns perimeter of triangle. } // Override the toString method public String toString() { //returns string description for thetriangle. // Implement it to return the three sides return "Triangle: side1 = " + side1 + " side2 = " + side2 + " side3 = " + side3; } } public abstract class GeometricObject { private String color = "white"; private boolean filled; private java.util.Date dateCreated; An abstract class’s purpose is to provide an appropriate superclass from which other classes can inherit and thus share a common design Classes that can be used to instantiate objects are called concrete classes. abstract class continued /** Construct a default geometric object */ protected GeometricObject() { dateCreated = new java.util.Date(); } /** Construct a geometric object with color and filled value */ protected GeometricObject(String color, boolean filled) { dateCreated = new java.util.Date(); this.color = color; this.filled = filled; } abstract class continued /** Return color */ public String getColor() { return color; } public void setColor(String color) {/** Set a new color */ this.color = color; } /*Return filled. Since filled is boolean, the get method is named isFilled */ public boolean isFilled() { return filled; } /** Set a new filled */ public void setFilled(boolean filled) { this.filled = filled; } /** Get dateCreated */ public java.util.Date getDateCreated() { return dateCreated; } abstract class continued @Override public String toString() { return "created on " + dateCreated + "\ncolor: " + color + " and filled: " + filled; } /** Abstract method getArea */ public abstract double getArea(); /** Abstract method getPerimeter */ public abstract double getPerimeter(); } Association relationships between classes & Aggregation relationships between classes & Composition relationships between classes Association Association represents a general binary relationship that describes an activity between two classes. Student 5..60 public class Student { /** Data fields */ private Course[] courseList; Take * Course 0..3 public class Course { /** Data fields */ private Student[] classList; private Faculty faculty; /** Constructors */ /** Methods */ /** Constructors */ /** Methods */ } Teach 1 Teacher Faculty public class Faculty { /** Data fields */ private Course[] courseList; /** Constructors */ /** Methods */ } } An association is usually represented as a data field in the class.20 Translation is not Unique for Association If you don’t need to know the courses a student takes or a faculty teaches, the data field courseList in Student or Faculty can be omitted. 21 Association Between Same Class Association (also aggregation) may exist between objects of the same class. For example, a person may have a supervisor. 1 Person Supervisor 1 public class Person { // The type for the data is the class itself private Person supervisor; ... 22 } Aggregation Between Same Class What happens if a person has several supervisors? Person m 1 Supervisor public class Person { ... private Person[] supervisors; } 23 Object Composition Composition is actually a special case of the aggregation relationship. Aggregation models has-a relationships and represents an ownership relationship between two objects. The owner object is called an aggregating object and its class an aggregating class. The subject object is called an aggregated object and its class an aggregated class. 24 Class Representation An aggregation relationship is usually represented as a data field in the aggregating class. For example, the relationship in Figure 10.6 can be represented as follows: public class Name { ... } public class Student { private Name name; private Address address; public class Address { ... } ... } Aggregated class Aggregating class 25 Aggregated class Aggregation and Composition Aggregation: special form of association Represents ownership relationship Aggregation models the has-a relationship. Composition: special form of aggregation object exclusively owned by aggregated object Composition Name Aggregation Person Address 26 class Person { private Heart heart; private List<Hand> hands; } In composition (Person, Heart, Hand), "sub objects" (Heart, Hand) will be destroyed as soon as Person is destroyed. In aggregation (City, Tree, Car) "sub objects" (Tree, Car) will NOT be destroyed class City { when City is destroyed private List<Tree> trees; private List<Car> cars } class StereoSystem { private boolean state ; StereoSystem() {} StereoSystem(boolean state) { this.state = state ; } System.out.println("Stereo System State: " + (state == true ? "On!" : "Off!")) ; } } class Car { private StereoSystem s ; Car() {} Car(String name, StereoSystem s) { this.s = s ; } public static void main(String[] args) { StereoSystem ss = new StereoSystem(true) ; // true(System is ON.) or false (System is OFF) Car c = new Car("BMW", ss) ; 7 } } Aggregation and Composition Both aggregation and composition represent a whole-part (has-a/part-of) association. The main differentiator between aggregation and composition is the lifecycle dependence between whole and part. In aggregation, the part may have an independent lifecycle, it can exist independently. When the whole is destroyed the part may continue to exist. For example, a car has many parts. A part can be removed from one car and installed into a different car. If we consider a business, before a car is destroyed, they remove all saleable parts. Those parts will continue to exist after the car is destroyed. Composition is a stronger form of aggregation. The lifecycle of the part is strongly dependent on the lifecycle of the whole. When the whole is destroyed, the part is destroyed too. For example, a building has rooms. A room can exist only as part of a building. The room cannot be removed from one building and attached to a different one. Design When we decide between aggregation and composition we need to answer the following question: can the part exist independently? For example The car-part relationship mentioned above is an aggregation, but if the business requirements state that “no part of a vehicle can be used for resale or as spare part; at the end of the amortization period the vehicle is destroyed” Then this will suggest a composition relationship between car and its parts. Java Implementation Objects do not need to be destroyed explicitly; An object is automatically “destroyed” when it is garbage collected. An object is garbage collected when it is not referenced by any other object. Regardless of the type of relationship – aggregation or composition – the part is referenced by the whole. If the whole is destroyed (garbage collected), then the part is no longer referenced by the whole. If there is no other object referencing the part then the part is destroyed too. The Difference Between Aggregation and Composition Is the variable that holds the part object accessible to objects other than the whole? If the answer is yes, then we have aggregation, If the answer is no then we have composition. Aggregation - Java sample code public class Car { private String make; private int year; private Engine engine; public Car(String make, int year, Engine engine) { this.make = make; this.year = year; this.engine = engine; } public String getMake() { return make; } public int getYear() { return year; } public Engine getEngine() { return engine; } } public class Engine { private int engineCapacity; private int engineSerialNumber; public Engine(int engineCapacity, int engineSerialNumber) { this.engineCapacity = engineCapacity; this.engineSerialNumber = engineSerialNumber; } public int getEngineCapacity() { return engineCapacity; } public int getEngineSerialNumber() { return engineSerialNumber; } } Aggregation Explanation The engine object is created outside and is passed as argument to Car constructor When this Car object is destroyed, the engine is still available to objects other than Car If the instance of Car is garbage collected the associated instance of Engine may not be garbage collected (if it is still referenced by other objects) Composition - Java sample code public class Car { private String make; private int year; private Engine engine; public Car(String make, int year, int engineCapacity, int engineSerialNumber) { this.make=make; this.year=year; engine = new Engine(engineCapacity, engineSerialNumber); } we create the engine using parameters passed in Car constructor only the Car instance has access to the engine instance when Car instance is garbage collected, the engine instance is garbage collected too*/ public String getMake() { return make; } public int getYear() { return year; } public int getEngineSerialNumber() { return engine.getEngineSerialNumber(); } public int getEngineCapacity() { return engine.getEngineCapacity(); } }