Class Diagram: A graphical model representing conceptual objects and their relationships
Two Types of Relationships:
- Inheritance:
- Instance Level: Child objects are special kinds of a parent object (is-a relationship)
- Class Level: Child classes are sub classes of a parent class
- Wrong: A child object is contained in a parent object (why?)
- Example 1:
- Employee, FullTimer, and PartTimer
- Account, Checking, and Savings
- Encapsulation Principle Revisit:
- private data for parent class must be changed into protected one
- behavioral members must be changed into virtual if child class needs to change their implementation.
- Abstract operation: operation in a parent class that has no implementation (function body). Abstract operations have to be implemented in child classes
- Abstract class: A parent class that has one or more abstract operations
- Interface: an abstract class that has nothing but abstract operations.
- The purpose of abstract classes and interfaces is to set up a programming contract for all all sub classes to observe
- Association --any other kinds of relationships if they are related, including containment (has-a relation), assignment, correspondence, etc
- Cardinality or multiplicity: quantify how one object is associated with how many other objects
- Example: Customer and Account
- Navigability:
- qualify whether one object commands or asks other objects to perform their operations (e.g.: Pilot --> Airplane)
- qualify whether one object refers to or contains other objects as a part of its data members (e.g., Order --> Product)
Implementation: Programming Inheritance and Associations
- Inheritance: if A is a sub class of B: class B {//} and class A:B {//} . Examples: Parttimer : Employee {//} to show that Parttimer is a sub class of Employee; Savings:Account {//}; Checking:Account {//}
- Associations:
- Navigability
- A --> B: Create B's object(s) inside A as instance variables
- A -- B: Create B's object(s) inside A as instances variables and create A's object(s) inside B as instance variables
- Cardinality:
- If maximum cardinality is 1, create a single object as instance variable
- If maximum cardinality is greater than 1 and fixed, create an array of objects as an instance variable
- If maximum cardinality is greater than 1 and not fixed, create a list of objects as an instance variable
- A --> B: class A has one (cardinality on B size is one) or more (cardinality on B side is many) B's instances as attributes
- A -- B class A has has one (cardinality on B size is one) or more (cardinality on B side is many) B's instances as attributes, and Class B has one (cardinality on A size is one) or more (cardinality on A side is many) A's instances as attributes
- Example: Customer -- Order --> Product
Python Implementations:
- Customer, Order, and Product, and Organization Customer
- Department and Employee
- Vehicle and Truck
- Account and CheckingAccount
class Product:
def __init__(self, sku, name, qoh, price):
self.sku = sku
self.name = name
self.qoh = qoh
self.price = price
def AddQuantity(self, num):
self.qoh += num
def InventoryValue(self):
returnself.qoh * self.price
class Customer:
def __init__(self, name):
self.name = name
self._orders = []
@property
def orders(self):
"""Returns the list of orders for this customer."""
returnself._orders
@orders.setter
def orders(self, orders):
self._order = orders
def add_order(self, order):
"""Adds an order and ensures the order knows its customer."""
if order notinself._orders:
self._orders.append(order)
# Synchronize: ensure the order's customer is set to this instance
order.customer = self
def __repr__(self):
returnf"Customer(name='{self.name}')"
def list_orders(self):
return [order.order_id for order inself._orders]
class Order:
def __init__(self, order_id, customer=None):
self.order_id = order_id
self._items = []
self._customer = None
if customer != None:
self.customer = customer
@property
def customer(self):
"""Returns the customer associated with this order."""
return self._customer
@customer.setter
def customer(self, new_customer):
"""Sets the customer and ensures the customer's order list is updated."""
if self._customer != new_customer:
self._customer = new_customer
# Synchronize: ensure this order is added to the customer's list
new_customer.add_order(self)
def __repr__(self):
return f"Order(id='{self.order_id}')"
def add_item(self, item):
if item notinself._items:
self._items.append(item)
def OrderTotal(self):
total = 0
for item inself._items:
total += item.price
return total
class OrgCustomer(Customer):
def __init__(self, name, credit_limit):
super().__init__(name)
self.credit_limit = credit_limit
def AdjustCreditLimit(self, new_limit):
self.credit_limit = new_limit
# Example Usage
p1 = Product("SKU001", "Laptop", 10, 999.99)
p2 = Product("SKU002", "Smartphone", 20, 499.99)
alice = Customer("Alice")
order1 = Order("ORD_001")
order2 = Order("ORD_002")
goodyear = OrgCustomer("Goodyear", 10000)
order1.add_item(p1)
order1.add_item(p2)
order2.add_item(p1)
# Linking from one side automatically updates the other
alice.add_order(order1)
goodyear.add_order(order2)
print(f"Customer's orders: {alice.orders}")
print(f"Order's customer: {order1.customer.name}")
alice.list_orders()
Advanced Coding Concepts on Inheritance: virtual operations, abstract operations, abstract classes, and interface

public abstract class Account
{
//if each account belongs to upt to a certain number of customers
//protected Customer[] customers;
//if each account belongs to an unknown numbers of customers
//protected List customers;
//if each account belongs to one customer
protected Customer customer;
protected int acctNo;
protected double balance;
//protected string acctType;
protected DateTime openDate;
public Account()
{
acctNo = 0;
balance = 0;
openDate = DateTime.Now;
//if each account belongs to upt to 5 customers
//customers = new Customer[5];
//if each account belongs to an unknown numbers of customers
//customers = new List();
//if each account belongs to one customer
customer = new Customer();
}
public Account(int newAcctNo, double newBalance, DateTime newOpenDate, Customer cust)
{
acctNo = newAcctNo;
balance = newBalance;
openDate = newOpenDate;
customer = cust;
}
public virtual void Credit(double amt)
{
balance = balance + amt;
}
public virtual void Debit(double amt)
{
if (balance < amt)
throw new Exception("insufficient fund");
else
balance = balance - amt;
}
public double GetBalace()
{
return balance;
}
public abstract double ComputeInterest();
}
public class Customer
{
private List<Account> accounts;
public Customer()
{
accounts = new List<Account>();
}
}
public class CheckingAccount : Account
{
private List<SavingsAccount> associtedSavings;
private int checksAllowed;
public CheckingAccount():base()
{
associtedSavings = new List<SavingsAccount>();
checksAllowed = 90;
}
public override double ComputeInterest()
{
//throw new NotImplementedException();
return 0;
}
}
public class SavingsAccount : Account
{
private CheckingAccount primaryChecking;
private double interestRate;
private DateTime validFrom;
private DateTime validUtil;
public override double ComputeInterest()
{
//throw new NotImplementedException();
if (validUtil > DateTime.Now)
{
TimeSpan ts = DateTime.Now - validFrom;
int years = ts.Days / 365;
return interestRate * balance * years;
}
else
{
TimeSpan ts = validUtil - validFrom;
int years = ts.Days / 365;
return interestRate * balance * years;
}
}
public SavingsAccount():base()
{
primaryChecking = new CheckingAccount();
interestRate = 0;
validUtil = DateTime.Now;
}
}
public class CD : Account
{
private double interestRate;
private DateTime maturity;
public CD():base()
{
interestRate = 0;
maturity = DateTime.Now;
}
public override double ComputeInterest()
{
//throw new NotImplementedException();
if (DateTime.Now < maturity)
return 0;
else
{
TimeSpan ts = maturity - openDate;
int years = ts.Days/365;
return balance * Math.Pow(1 + interestRate, years);
}
}
public override void Debit(double amt)
{
if (DateTime.Now < maturity)
throw new Exception("not matured yet");
else
base.Debit(amt);
}
}
Homework:
- Reading: Chapter 6 of LIU (2020)
- Exercises: Correctness Questions: online; Hands-on Questions:
===============================
1. Create a Library and Book association
Create a class Library with:
Include methods:
Use a Book class with:
-
title
-
author
-
method description()
2. Create a Team and Player association
Create a class Player with:
Create a class Team with:
Include methods:
3. Inheritance: Animal and Cat
Create a parent class Animal with:
Methods:
Create a child class Cat that inherits from Animal.
Override:
Add method:
4. Inheritance: Person, Student, and Professor
Create a parent class Person with:
Method:
Create child classes:
Each child should override introduce().
|