class: middle ### Announcements .small[ - No Recitations and Lab Sessions this week. - Exercise 1 (and explainer video) will be released today. Exercise 2 and 3 build upon Exercise 1. - Reminder: Self Diagnostic Quiz 3 and Vim / PE Environment quizzes. - Practice PE0s will be released this week for your self study. - File a ticket for Timetable Clashes for PE1. - Select the correct category. - No need to file a ticket if it conflicts with your CS2030S recitations and labs. ] --- class: middle, center ## CS2030
s
### Programming Methodology II --- class: middle, center ## Lecture 3 ### 27 January 2025 --- class: middle,left ### Quick Recap - Inheritance - Overridden methods (toString) - Class Hierarchy - java.lang.Object --- class: middle,left ### Topics covered today: - Overloading - Polymorphism - Method Invocation - Liskov Substitution Principle - Abstract Class - Interface (Unit 13 to Unit 18) --- class: middle,wide ### Subtyping with Reference Types If `ColoredCircle` $<:$ `Circle` .small[```Java ColoredCircle c = new Circle(p, 0); // error Circle c = new ColoredCircle(p, 0, blue); // OK ```] --- class: middle,wide ### Passing arguments to methods .tiny[```Java public boolean circleMethod(Circle c) { .. } public boolean coloredCircleMethod(ColoredCircle c) { .. } ```] If `ColoredCircle` $<:$ `Circle` .small[```Java Circle c = new Circle(p, 0); ColoredCircle cc = new ColoredCircle(p, 0, blue); circleMethod(cc); // OK coloredCircleMethod(c); // error ```] --- class: middle,wide ### Compile-Time Type vs. Run-Time Type .small[```Java Circle c = new ColoredCircle(p, 0, blue); c = new Circle(p, 0); ```] --- class: middle,center # Overriding `equals` method --- class: middle,left .small[ ```Java Point p1 = new Point(0, 0); Point p2 = new Point(0, 0); p1.equals(p2); ``` ] --- class: middle,left .small[ ```Java @Override public boolean equals(Object obj) { if (obj instanceof Point) { Point point = (Point) obj; return (point.x == this.x && point.y == this.y); } return false; } ``` ] --- class: middle,left .small[ ```Java Circle c1 = new Circle(new Point(0, 0), 10); Circle c2 = new Circle(new Point(0, 0), 10); c1.equals(c2); ``` ] --- class: middle,left .small[ ```Java @Override public boolean equals(Object obj) { if (obj instanceof Circle) { Circle circle = (Circle) obj; return (circle.c.equals(this.c) && circle.r == this.r); } return false; } ``` ] --- class: middle,center # Overloading Methods with the same name but a different method signature --- class: middle,left .small[ ```Java public boolean contains(Point p) { : } public boolean contains(double x, double y) { : } ``` ] --- class: middle,left .small[ ```Java public boolean equals(Circle o) { : } public boolean equals(Object o) { : } ``` ] --- class: middle,center # Polymorphism ### _many_ _forms_ --- class: middle,left .small[ ```Java void say(Object obj) { System.out.println("Hi, I am " + obj.toString()); } ``` ] .small[ ```Java Point p = new Point(0, 0); say(p); Circle c = new Circle(p, 4); say(c); ``` ] --- class: middle,left .small[ ```Java void say(Object obj) { System.out.println("Hi, I am " + obj.toString()); } ``` ] Which `toString` method that executed is decided _during run-time_, depending on the run-time of `obj`. This is known as _dynamic binding_. --- class: middle,center ### But this is a lot of power, and with great power... --- class: middle,center # Dynamic Binding How does Java determine which method implementation to execute? --- class: middle,left .small[ ```Java boolean contains(Object[] array, Object obj) { for (Object curr : array) { if (curr.equals(obj)) { return true; } } return false; } ``` ] Java determines which method implementation to execute by using a two step process. --- class: middle,left, wide ### Step 1: At compile-time `curr.equals(obj)` - Identify the compile-time type of `curr` (`Object`) - Check the class `Object` for methods called `equals` - There is only one method `Object::equals(Object)` - Store this method descriptor in the generated bytecode --- class: middle,left .small[ ```Java circle.equals(circle); ``` ] What if there are multiple methods that can correctly accept the argument? .small[ ```Java boolean equals(Circle c) { : } ``` ```Java @Override boolean equals(Object c) { : } ``` ] We choose the _most specific_ one. --- class: middle,left ### Most specific? A method $M$ is more specific than a method $N$ if the arguments to $M$ can be passed to $N$ without compilation error. --- class: middle,left The method `equals(Circle)` is more specific than the method `equals(Object)` if the arguments to `equals(Circle)` can be passed to `equals(Object)` without compilation error. --- Consider the `Circle` class with two `equals` methods: .tiny[ ```Java @Override boolean equals(Object c) { boolean equals(Circle c) { : : } } ``` ] `equals(Circle)` is more specific than `equals(Object)`. Every `Circle` is an `Object`, but not every `Object` is a `Circle`. Java stores this method descriptor in the generated bytecode. --- class: middle,left, wide ### Step 2: At run-time `curr.equals(obj)` - The method descriptor from Step 1 is retrieved - The run-time type of the target `curr` is determined - Java then looks for an accessible method with the matching descriptor in that class. Continued... --- class: middle,left, wide ### Step 2: At run-time `curr.equals(obj)` - If no such method is found, the search will continue up the class hierarchy. - The first matching descriptor will be the one that is executed --- class: middle,left Class methods do not support dynamic binding. The method to invoke is resolved statically during compile time. --- class: middle,center ## Liskov Substitution Principle (LSP) Let $\phi(x)$ be a property provable about objects $x$ of type $T$. Then $\phi(y)$ should be true for objects $y$ of type $S$ where $S <: T$. --- class: middle,center ## Liskov Substitution Principle (LSP) If $S$ is a subclass of $T$, then an object of type $T$ can be replaced by that of type $S$ without changing the _desirable property_ of the program --- class: middle,center ## Liskov Substitution Principle (LSP) A _subclass_ should not break the expectations set by the _superclass_ --- class: middle,center ## Substitution We can only substitute with an instance of the same _type_ or a _subtype_. --- class: middle,center ### Still too abstract? Let's look at an example... --- class: middle,center ### How can we prevent people inheriting from our code? We can use the java keyword `final` For example `java.lang.Math` --- class: middle,left .small[ ```Java double findLargest(Circle[] array) { double maxArea = 0; for (Circle curr : array) { double area = curr.getArea(); if (area > maxArea) { maxArea = area; } } return maxArea; } ``` ] --- class: middle,center ## Abstract Classes _A class that cannot be instantiated_ --- class: middle .small[ ```Java abstract class Shape { private int numOfAxesOfSymmetry ; public boolean isSymmetric() { return numOfAxesOfSymmetry > 0; } abstract public double getArea(); } ``` ] --- class: middle,center ## Interface _"What can it do?"_ --- ```Java interface GetAreable { double getArea(); } ``` --- class: middle ### Implementing an Interface .tiny[ ```Java class Circle extends Shape implements GetAreable { : public double getArea() { : } : } ``` ] --- class: middle,wide .small[ ```Java double findLargest(GetAreable[] array) { double maxArea = 0; for (GetAreable curr : array) { double area = curr.getArea(); if (area > maxArea) { maxArea = area; } } return maxArea; } ``` ] --- class: middle, center ### Another rule for Reference Types If a class `C` implements an interface `I` then `C` $<:$ `I` --- class: middle In Java: - A class can extend at most one class - A class can implement zero or more interfaces - An interface can extend zero or more interfaces --- class: top,center ### Concrete vs Abstract --- class: middle,left ### Reminders .small[ - No Recitations and Lab Sessions this week. - Exercise 1 (and explainer video) will be released today. Exercise 2 and 3 build upon Exercise 1. - Reminder: Self Diagnostic Quiz 3 and Vim / PE Environment quizzes. - Practice PE0s will be released this week for your self study. - File a ticket for Timetable Clashes for PE1. - Select the correct category. - No need to file a ticket if it conflicts with your CS2030S recitations and labs. ] --- class: middle,left background-color: darkred ## Happy Lunar New Year! --- class: bottom .tiny[ Version: v1.0 Last Updated: Sat Jan 25 18:00:00 +08 2025 ]