Lecture 6
Object construction, the 'this' keyword, and inheritance mechanisms
This work is licensed under CC BY-NC-SA 4.0
© Way-Up 2025
package fr.tbr.exercises;
/**
* Example of a car, constructor with
* a "color" parameter
* @author Tom
*/
public class Car {
private String color;
public Car(String color) {
this.color = color;
}
}
this keyword.this allows to access to the current instance valuesthis keyword can be used in any
non-static methods
/**
* return the calculated interest on one year
* warning, this method updates the balance with the result of that computation
* @return the interest
*/
public double calculateInterest(){
double result = this.interestRate * this.balance;
this.balance += result; //equivalent to this.balance = this.balance + result
return result;
}
this keyword is
strongly recommended
IS-A relationship
public class Quadrilateral {
private double sideA;
private double sideB;
private double sideC;
private double sideD;
/*...*/
public double calculatePerimeter(){
return this.sideA + this.sideB
+ this.sideC + this.sideD;
}
}
public class Rectangle extends Quadrilateral{
public Rectangle(double height, double width)
{
super (height, height, width, width);
}
}
super keyword: it allows the access of the inherited Class (here the
Quadrilateral Class)
calculatePerimeter()
method again
In the geometry example found here,
add the Ellipse object and try to generalize the Circle class methods
super object methodsabstract classespublic abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// Abstract method - no implementation
public abstract double calculateArea();
// Concrete method - has implementation
public String getColor() {
return this.color;
}
}
abstract keyword for the classpublic class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color); // Call parent constructor
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
@Override annotation to indicate you're implementing an abstract methodinterfacesDrivable and Lockablepublic interface Drawable {
// All methods in interfaces are implicitly public and abstract
void draw();
double getArea();
// Since Java 8: default methods with implementation
default void display() {
System.out.println("Drawing shape with area: " + getArea());
}
}
interface keyword instead of classpublic abstractdefault methods (since Java 8) with implementationstatic methodspublic class Rectangle extends Shape implements Drawable, Comparable<Rectangle> {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public void draw() {
System.out.println("Drawing a " + color + " rectangle");
}
@Override
public double getArea() {
return calculateArea();
}
@Override
public int compareTo(Rectangle other) {
return Double.compare(this.calculateArea(), other.calculateArea());
}
}
| Feature | Abstract Class | Interface |
|---|---|---|
| Inheritance | Can extend only one | Can implement multiple |
| Fields | Can have any fields | Only public static final |
| Methods | Abstract + concrete | Abstract + default + static |
| Constructor | Yes | No |
| Use case | IS-A relationship | CAN-DO behavior |
public class ShapeDemo {
public static void main(String[] args) {
// Polymorphism: treat all shapes uniformly
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle("Red", 5.0));
shapes.add(new Rectangle("Blue", 4.0, 6.0));
shapes.add(new Triangle("Green", 3.0, 4.0));
// Calculate total area using polymorphism
double totalArea = 0;
for (Shape shape : shapes) {
totalArea += shape.calculateArea(); // Calls correct method
System.out.println(shape.getClass().getSimpleName() +
" area: " + shape.calculateArea());
}
System.out.println("Total area: " + totalArea);
}
}
// Abstract base class
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public abstract double calculateArea();
public abstract double calculatePerimeter();
}
// Interface for drawable objects
public interface Drawable {
void draw();
default String getDescription() {
return "A drawable shape";
}
}
// Concrete implementation
public class Circle extends Shape implements Drawable, Comparable<Circle> {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
@Override
public void draw() {
System.out.println("Drawing a " + color + " circle with radius " + radius);
}
@Override
public int compareTo(Circle other) {
return Double.compare(this.radius, other.radius);
}
}
Create a complete geometry system with the following:
Shape class with:
color fieldcalculateArea() and calculatePerimeter()getColor()Drawable interface with a draw() methodCircle (radius)Rectangle (width, height)Triangle (base, height)ShapeManager class that:
Comparable to sort them by area