Unit 5: Classes and Object (Part 2)

Classes and Class Diagrams

Classes are abstractions that specify the attributes and operations/methods of a set of objects. Objects are entities that encapsulate state and behavior.

  1. Public(+)

  2. Protected(#)

  3. Packaged(~)

  4. Private(-)

A class's attributes are the pieces of information that represent the state of an object. These attributes can be represented inside the class box, known as inline attributes or by association with another class.

Operations in UML are specified on a class diagram with a signature that is at minimum made up of a visibility property, a name, a pair of parentheses in which any parameters that are needed for the operation to do its job can be supplied, and a return type, as shown

Sometimes association can have attributes and operations. Such association is called association class.
• A common problem in OO modeling is that when you have a many-to-many relationship between two classes. For example, consider the following association.
    • What will happen if each Person has a salary with each Company they are employed by? Where should the salary be recorded – in the Person class or in the Company class?
• The answer is that the salary is a property of the association itself.


A group of system administrators must keep track of which computers are assigned to computer users in the community they support. Currently this is done by hand, and the system administrators want to automate this task and build The Computer Assignment System (CAS) to ease their workload.
CAS will keep track of computers, computer users, and assignments of computers to users with the date of assignment; answer queries; and produce reports about users, computers, and assignments. Developers in the same enterprise will implement CAS.

Aggregation

Aggregation means putting objects together to make a bigger object.
• Aggregations usually form a whole-part hierarchy.
• In UML, aggregation is treated as a constrained form of association, and is represented by using an empty diamond arrowhead next to the owning class

The parts can sometimes exist independently of the whole.

“has”
• In the top-down explanation, the phrase is "has" (Book "has" Chapter, for example).
“is-part-of”
• In the bottom-up interpretation, the phrase is "is part of" (Chapter "is part of" Book, for instance).

Composition

A stronger form of aggregation and has similar semantics

Like aggregation, it is a whole-part relationship and is both transitive and asymmetric.
• The key difference between aggregation and composition is that in composition the parts have no independent life outside of the whole.
• Furthermore, in composition each part belongs to one and only one whole.

Generalization (Inheritance)

The terms is a part of and is a kind of are your tools to decide whether a relationship between two classes is aggregation or generalization.
• In UML, the generalization arrow is used to show that a class is a type of another
class
• In UML, inheritance is termed generalization because parent classes describe a more general type, which is then made more specialized in child classes.

Inheritance involves a superclass and a subclass relationship

The subclass is stronger than the superclass because you can use the superclass and more

Constructors are not inherited. When a subclass is instantiated, the superclass default constructor is executed first.

MIDTERM

UML diagrams

Study Book library management example

4 questions

  1. UML

  2. short

  3. short

  4. long

Paper and pencil coding :/

Methods Overloading and Overriding

Overloading

Multiple methods within the same class and/or the derived class can have the same name as an overloading.
Java distinguishes the overloading methods by noting the parameters:
➢ Different numbers of parameters (and/or) (must)
➢ Different types of parameters (must)
➢ Different return (or same) types (could be void). (optional)
This is called the signature of the method. Overloaded methods must have different signatures

Overloading:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    public double add(double a, double b) {
        return a + b;
    }
    public String add(String a, String b) {
        return a + b;
    }

    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        int result1 = calculator.add(2, 3);
        double result2 = calculator.add(2.5, 3.7);
        String result3 = calculator.add("Hello, ",                                         "world!");

        System.out.println(result1); // Output: 5
        System.out.println(result2); // Output: 6.2
        System.out.println(result3); // Output: Hello,                                                 world!
    }
}

“VERY VERY IMPORTANT” - Ouda

  1. Implements “compile time polymorphism”

  2. method call determined at compile time

  3. Occurs between the methods in the same class and/ or subclass

  4. Have same name but different signature

  5. error caught at compile time

Overriding

A subclass may have a method with the same signature as a superclass method. The subclass method overrides the superclass method. This is known as method overriding.

Same parameters and same return type.

“VERY VERY IMPORTANT” - Ouda

Overriding

  1. Implements “runtime polymorphism”

  2. Method call is determined at runtime based on the object type

  3. Occurs between superclass and subclass

  4. Same signature

  5. error effect visible at runtime

public final void message()//cannot be overridden

“final” cannot be overridden

Ensures the superclass method is used by subclass rather than a modified version

Polymorphism

    A reference variable can reference instances of classes that are derived from the variable’s class.

GradedActivity exam;

We can use the exam variable to reference a GradedActivity object.

exam = new GradedActivity();


The GradedActivity class is also used as the superclass for the FinalExam class.
An object of the FinalExam class is a GradedActivity object.

exam = new FinalExam(50, 7);

A GradedActivity variable can be used to reference a FinalExam object.

GradedActivity exam = new FinalExam(50, 7);
//object of Final exam but can only call GradedActivity methods
//if there is an override in the subclass, it will still call the super


This statement creates a FinalExam object and stores the object’s address in the exam variable.
➢ This is an example of polymorphism.

//If we declare 
Supclass aa = new Subclass;
//To use a unique method from the subclass we need to cast the reference of the superclass to the subclass
((SubClass) aa).uniqueMethod();

toString Method

All objects have a toString method that returns the class name and a hash of the memory address of the object.

we can @override the default method with our own to print more useful info

@override
public String toString(){
    String str = "whatever bruh";
    return str;
}

System.out.println(object);

//use this to check if equal
Stock stock1 = new Stock("GMX", 55.3);
Stock stock2 = new Stock("GMX", 55.3);
if (stock1.equals(stock2))
    System.out.println("Same object");
else
    System.out.println("Not the same");

== just compares the address of the object

copying objects

public Stock(Stock object2) {
    symbol = object2.symbol;
    sharePrice = object2.sharePrice;
}

// Create a Stock object
Stock company1 = new Stock("XYZ", 9.62);
//Create company2, a copy of company1
Stock company2 = new Stock(company1);

the this reference can also be used to call a constructor from another constructor

public Stock(String sym){
    this.(sym, 0.0)//must be the first statement in the constructor
}

Inner Classes and Enumerated Types

Classes can have other classes nested within them!

  1. An outer class can access the public members of an inner class.

  2. An inner class is not visible or access to code outside the outer class.

  3. An inner class can access the private members of the outer class.

    //outerclass$innerclass.class
    RetailItem$CostData.class;

How to define an inner class ^

inner classes should be private

// This class uses an inner class.
public class RetailItem {
    private String description; // Item description
    private int itemNumber; // Item number
    private CostData cost; // Cost data
    // RetailItem class constructor
    public RetailItem(String desc, int itemNum,
    double wholesale, double retail) {
        description = desc;
        itemNumber = itemNum;
        cost = new CostData(wholesale, retail);
    }
    // RetailItem class toString method
    public String toString() {
        String str; // To hold a descriptive string.
        // Create a formatted string describing the item.
            str = String.format("Description: %s\n" +
                                "Item Number: %d\n" +
                                "Wholesale Cost: $%,.2f\n" +
                                "Retail Price: $%,.2f\n",
                                description, itemNumber,
                                cost.wholesale, cost.retail);
            return str; // Return the string
    }
    // CostData Inner Class
    private class CostData {
        public double wholesale, // Wholesale cost
        retail; // Retail price
        // CostData class constructor
        public CostData(double w, double r) {
            wholesale = w;
            retail = r;
        }
    }
}


/**
* This program demonstrates the RetailItem class,
* which has an inner class.
*/
public class InnerClassDemo
{
    public static void main(String[] args)
    {
        // Create a RetailItem object.
        RetailItem item = new RetailItem("Candy bar", 17789,
        0.75, 1.5);
        // Display the item's information.
        System.out.println(item);
    }
}

ENUMERATION

//Known as an enum
//Requires declaration and definition like a class
//Syntax:
enum typeName { one or more enum constants }
//Definition:
enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY }
//Declaration:
Day WorkDay; // creates a Day enum
//Assignment:
Day WorkDay = Day.WEDNESDAY;

// This program demonstrates an enumerated type.
public class EnumDemo {
    // Declare the Day enumerated type.
    enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,     FRIDAY, SATURDAY }
    public static void main(String[] args)
        {
        // Declare a Day variable and assign it a value.
        Day workDay = Day.WEDNESDAY;
        // The following statement displays WEDNESDAY.
        System.out.println(workDay);
        // The following statement displays the ordinal
        // value for Day.SUNDAY, which is 0.
        System.out.println("The ordinal value for " + Day.SUNDAY +                             " is " + Day.SUNDAY.ordinal());
        // The following statement displays the ordinal
        // value for Day.SATURDAY, which is 6.
        System.out.println("The ordinal value for " + Day.SATURDAY                             + " is " + Day.SATURDAY.ordinal());
        // The following statement compares two enum constants.
        if (Day.FRIDAY.compareTo(Day.MONDAY) > 0)
            System.out.println(Day.FRIDAY + " is greater than " +                                             Day.MONDAY);
        else
            System.out.println(Day.FRIDAY + " is NOT greater than                                     " + Day.MONDAY);
    }
}

If the method public void finalize(){} is included in a class, it will run just prior to the garbage collector reclaiming its memory

CRC Card

Class responsibilities and collaborations are used to document what a class is responsible for knowing and what it is responsible for doing.

Abstract Classes

abstraction is a key concept that allows you to model complex systems by focusing on the essential features and ignoring the unnecessary details.

The abstract class is an important modeling concept that makes parent general enough for reusability.
An abstract class is a parent where not all its behaviors (methods) are implemented, and that will not have direct instance objects.

abstract class cannot be instantiated, but other classes are derived from it as a superclass for other classes.
A class becomes abstract when you place the abstract keyword in the class definition.

public abstract class ClassName

If any part of a class is declared abstract, then the class itself also needs to be declared as abstract.

An abstract method has no body and must be overridden in a subclass.
An abstract method is a method that appears in a superclass but expects to be overridden in a subclass.
An abstract method has only a header and no body.



AccessSpecifier abstract ReturnType MethodName(ParameterList);

Notice that the keyword abstract appears in the header, and that the header ends with a semicolon.
Any class that contains an abstract method is automatically abstract.
If a subclass fails to override an abstract method, a compiler error will result.
Abstract methods are used to ensure that a subclass implements the method.

Interfaces

Interfaces in Java provide a way to achieve abstraction by defining a contract that classes must adhere to without specifying the implementation details.
An interface is like an abstract class that has all abstract methods. It cannot be instantiated, and all of the methods listed in an interface must be written elsewhere.
The purpose of an interface is to specify behavior for other classes. An interface looks similar to a class, except: the keyword interface is used instead of the keyword class, and the methods that are specified in an interface have no bodies, only headers that are terminated by semicolons.

//All methods specified by an interface are public by default.
//A class can implement one or more interfaces.
// Relatable interface
public interface Relatable {
    boolean equals(GradedActivity g);
    boolean isGreater(GradedActivity g);
    boolean isLess(GradedActivity g);
}

public class FinalExam implements Relatable

When an interface variable references an object:

  • only the methods declared in the interface are available,

  • explicit type casting is required to access the other methods of an object referenced by an interface reference.

interface MyInterface {
    void myMethod();
}

class MyClass implements MyInterface {
    public void myMethod() {
        System.out.println("Implementation of myMethod");
    }

    public void anotherMethod() {
        System.out.println("Another method");
    }

}

public class Main {
    public static void main(String[] args) {
        MyInterface myInterfaceObj = new MyClass();
        myInterfaceObj.myMethod(); // Accessible directly
    // myInterfaceObj.anotherMethod(); // Not accessible directly
        ((MyClass) myInterfaceObj).anotherMethod(); // Explicit     type casting
    }
}


An inner class is a class that is defined inside another class in an anonymous inner class. An anonymous inner class is an inner class that has no name.
An anonymous inner class must implement an interface or extend another class.
Useful when you need a class that is simple, and to be instantiated only once in your code.


ClassOrInterfaceName objectName = new ClassOrInterfaceName() {
(Fields and methods of the anonymous class...)
};


A functional interface is an interface that has only one abstract method.
A lambda expression can be used to create an object that implements the functional interface and overrides its abstract method.
In Java 8, these features work together to simplify code, particularly in situations where you might use anonymous inner classes.