Tasks studies - laboratory
Inheritance
Inheritance is one of the fundamental mechanisms of object-oriented programming. This mechanism allows defining new classes based on existing ones.
The word “inheritance” is associated with transferring assets from one person to another in daily life. The analogy in Java is not far from this. Inheritance means that one class inherits methods and variables from another class.
Inheritance in Java is a ubiquitous and powerful mechanism. Almost every class—in fact, every class except java.lang.Object
—inherits from another class. Every class implicitly inherits from the mentioned Object
class.
What do we inherit from the Object
class? Several methods, including the equals(...)
method, which checks the equality of objects. This allows us to compare objects of any type with each other using the same method. Another method we inherit from the Object
class is toString()
. This method returns a textual representation of an object, regardless of its type.
Here’s an example of declaring inheritance and how methods defined in a superclass are inherited by a subclass. First, let’s define a Product
class that could describe items we sell in our online store. This class has a method that returns the product price and another method for setting the price when an object is created. Example code:
class Product {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
A book is a product and, like any product, it has a price. Since a book is a product, it also has all the features of a product. The class describing a book object should therefore inherit from the class describing a product, i.e., the Product
class. Example implementation of the class modeling book-type products:
class Book extends Product {
private int pagesNum;
public Book(double price, int pagesNum) {
this.setPrice(price);
this.pagesNum = pagesNum;
}
public int getPagesNum() {
return pagesNum;
}
}
Note the extends
keyword in the class declaration. This indicates that the Book
class inherits from the Product
class.
In the Book
constructor, we used the inherited setPrice(...)
method to set the book price. Furthermore, the Book
class inherits not only the methods defined in the Product
class, i.e., setPrice(...)
and getPrice()
, but also the methods inherited by Product
from the Object
class. Since the Product
class does not explicitly inherit from any class, it implicitly inherits from the Object
class. Inheritance is transitive, so the methods inherited by the Product
class are also passed on to the Book
class.
Method Overriding
Overriding a method involves re-implementing a method inherited from a superclass. This mechanism allows us to adapt method implementations to the specifics of the subclass.
For example, every class inherits the toString()
method from the Object
class. This method is supposed to return a textual description of an object. By default, it returns the class name and an uninformative hash code. This description is inadequate and should be improved. We can achieve this by overriding the toString()
method in our class. In the Book
class, the method could be implemented as follows:
class Book extends Product {
public String toString() {
return "Book '" + getTitle() + "', ISBN: " + getISBN();
}
// Methods getTitle(), getISBN(), and others needed in the Book class
}
Polymorphism
The benefits of inheritance would be very limited without polymorphism. Polymorphism allows objects of different subclasses of a common type to be treated in the same way. Let’s see how this works and how it simplifies programming.
Since a book is a product, in Java, this means that the Book
class inherits from the Product
class. Therefore, we can treat a book as a product. We can assign an object of type Book
to a reference of type Product
:
Product myProd = new Book(39.90, 210);
Of course, our store will also sell other items, not just books.
LINK
LINK
We will have classes such as MusicCD
, GameCD
, and AppCD
representing CDs or DVDs with music, games, and applications. All of these classes will inherit from the Product
class and can be processed in the system as products. For example:
Product myProd = new MusicCD(19.90, "The Beatles", "A Hard Day's Night");
Then:
myProd.getPrice();
To implement an online store cart that stores selected items and calculates the total order value, we can iterate through the product collection in the cart and call the getPrice()
method on each product. The sum of these prices will be the order value.
Polymorphism combined with method overriding can produce even more interesting results. For example, we could define a BonusPackage
product representing a bundle of products offered at a promotional price. In the BonusPackage
class, we can override the getPrice()
method so that it sums up the prices of all products in the package and applies a discount, e.g., 10%.
Introducing a BonusPackage
product does not require changes to the cart class or the functionality for calculating the order value. As before, we sum the results of the getPrice()
method for each object. For the algorithm, it doesn’t matter that some objects (those of type BonusPackage
) have a modified implementation of the getPrice()
method.
Implement a class Osoba
. This class should store the following values:
name
, surname
, date of birth
, gender
and include behaviors such as a method returning information about the person. Next, define classes inheriting from the Osoba
class:
Student – the class should include the following:
a) Fields:
b) Methods:
Osoba
class). Use the toString()
method.Wykładowca – design this class analogously to the Student
class, showcasing creativity.
LINK
Create a class Punkt2D
that stores information describing a point on a 2D plane (coordinates x
and y
). Include two constructors:
Implement a method that generates random coordinates for a point on the plane in the range of -10 to 10. Override the toString()
method to display information about the point’s coordinates.
Next, create a Punkt3D
class representing a 3D point, extending the Punkt2D
class with an additional field z
for the third dimension. Override the coordinate generation method to include the z
dimension. Override the toString()
method to display information about the 3D point’s coordinates.
In a test class, create objects of both classes and test their functionality. Then create two 100-element arrays:
Punkt2D
class named array2D
.Punkt3D
class named array3D
.For all elements in both arrays, generate random points using the previously implemented methods. Check if there are elements in array2D
and array3D
with matching x
and y
coordinates (i.e., if there exist points Punkt2D(x1, y1)
and Punkt3D(x2, y2, z2)
such that x1 = x2
and y1 = y2
). If such pairs exist, print them to the screen using the toString()
method.