User Tools

Site Tools


java_fundamentals

Java is an Object Oriented language

What does it actually mean? Object Oriented programming is a paradigm for a more abstract programming. At the beginning programs where written in a procedural fashion: a list of operation was made and the computer would execute it. A first simplification to reduce the code, and the amount of bugs is to group procedures in functions.

Why do we make programs? Because we want them to provide some answers! For instance, let's say we want to perform some linear algebra, then we define a series of functions to do things on matrices, like calculate the determinant. This works brilliantly, however we have to deal with matrices all the time, and the big leap of object oriented programming is that we put this procedures inside the matrix object! So, once we create the object we immediately are able to calculate the determinant!

The key element is the object, which is characterized by its state and by methods to change it. The analogy with real life objects clarifies immediately. Take an object like a Car: its state could be on/off and methods to change it (the key), would be startEngine() and stopEngine().

With this ingredients our program can be made by a more or less complex network of objects interacting with each other.

There are a number of characteristics of OOP:

Classes and Objects

An object is characterized by its state and by methods to change it. An Object is an instance of a class, i.e. it exists only when some memory has been allocated to hold it.

Borrowing from C++, a class is a special type of struct that allows its members to be functions and not just variables as in C.

Encapsulation

Encapsulation means that we can hide the members of a class inside it(functions or variables), exposing only what we want the user to be able to change. It is an effective way to protect our programs from crashes!

In the previous example, some member variables could be the number of rows and columns. We don't want to loose data by accidentally changing the matrix size, then the data may be protected by allowing the user to access (modify) them only with some methods that the author of the class writes. In the following code, the matrix size M and N, and the data itself are private and can be accessed only with appropriate methods:

public class Matrix {
    private int N=0, M=0;
    private double[][] data;
    public Matrix(int n, int m){
        if (n > 0 && m > 0) {
            N = n;
            M = m;
	    data = (double[][]) Array.newInstance(double.class, n, m);			
	} else {
	    throw new IllegalArgumentException ("Error with dimensions: " + n + " , " + m);
	}
    }
    public int getRows() {return N;}
    public int getCols() {return M;}
 
    /**
    * data setter
    */
    public void set(int row, int col , double val){
        if ((row >= 0 && row < N) && (col >= 0 && col < M))
	    data[col][row] = val; //rows and cols are inverted otherwise
	}
    /**
    * data getter
    */
    public double get(int row, int col) throws IllegalArgumentException{
	if ((row >= 0 && row < N) && (col >= 0 && col < M))
		return data[col][row];
	else throw new IllegalArgumentException("Cannot access at position: " + posX + " , " +posY);
    }
}

Inheritance

One other fundamental characteristic of OOP is inheritance, a feature that permits to reuse code and extend existing code very naturally.

A class may be extended by another. When extending one concept with one more specific, the new one will have all the characteristics of the first but will have some particular characteristics. The same applies to classes

Animal.java
package nature;
 
public class Animal {
    public String commonName;
    protected boolean isMarine = false;
 
    public static void main(String[] args){
 
    	Fish goldie = new GoldFish("Goldie");
    	System.out.println(goldie.commonName + " " + goldie.getLivesInFreshWater() + " " + goldie.isMarine);
    	Animal agoldie = goldie;
		System.out.println(agoldie.commonName + " " + agoldie.isMarine);
    }
} 
 
class Fish extends Animal {
    protected boolean livesInFreshWater = false;
    public boolean getLivesInFreshWater(){return livesInFreshWater;}
    public Fish(){
    	this.isMarine = true; // a fish lives in water!!
    }
 
}
 
class GoldFish extends Fish {
    private String my_name;
    public GoldFish(String my_name){
        this.my_name = my_name;
        this.commonName = "Gold Fish";
        this.livesInFreshWater = true;
    }
    public GoldFish() {
        this("Goldie");
    }
    public String getName(){
        return my_name;
    }
}

In this way a GoldFish is a subclass of a Fish, which it is a subclass of an Animal. GoldFish inherits the characteristics of the superclasses: livesInFreshWater and getLivesInFreshWater(), and commonName. It may implement new methods or override methods in the superclasses. However there are limitations on how this overriding can take place. This limits are dictated by the polymorphism.

Polymorphism

Probably the most interesting feature of OOP is polymorphism or the ability to treat an object for what it is or for what its superclasses are! For instance, you can treat a GoldFish like your pet, and give it a name or treat it like a Fish just keep it in water, or like an Animal

This concept is related to the inheritance: because a GoldFish is also a Fish, we can treat it as a Fish. And it is sufficient for us to keep it alive by knowing whether it will survive in fresh water or not. When we treat it like a Fish, we won't know its name! Because with Fish we don't have a method getName() and not even a member to store the name.

Fish goldie = new GoldFish("Goldie");
 
System.out.println(goldie.commonName + " " + goldie.getLivesInFreshWater()); // outputs "Gold Fish true"
 
Animal agoldie = goldie;
System.out.println(agoldie.commonName + " " + agoldie.isMarine); // outputs "Gold Fish true"

This fact is particularly interesting! We can treat an object as it is (its reference type) or as if it were a superclass (or an interface it implements!). In such a case we loose the ability to use all the characteristics of the class, but we must retain the characteristics of the superclass(es).

Because of polymorphism we see that there are a number of restrictions to the way you can extend classes or implement interfaces.

java_fundamentals.txt · Last modified: 2017/09/14 11:03 by 130.246.76.246