Difference between revisions of "Object-Oriented Concepts and Constructs"

From Sinfronteras
Jump to: navigation, search
(Class vs Object vs Instance)
Line 18: Line 18:
 
===Instance===
 
===Instance===
 
An instance is a unique copy of a Class that representing an Object. When a new instance of a class is created, the JVM will allocate a room of memory for that class instance.
 
An instance is a unique copy of a Class that representing an Object. When a new instance of a class is created, the JVM will allocate a room of memory for that class instance.
 +
 +
===Otro punto de vista===
 +
Luego de leer distintos fuentes para tratar de entender los conceptos de «Class vs Object vs Instance» me ha parecido que los conceptos de «Object and Instance» no están bien diferenciados... es decir no encuentro una definición que verdaderamente me convenza de la diferencia entre estos dos conceptos.
 +
 +
Entonces, encontré otra fuente que plantea lo siguiente:
 +
https://www.javatpoint.com/q/3420/difference-between-instance-and-object-?
 +
 +
Object and Instance are the same thing in most object-oriented languages. "Instance of a class" is just how the term "object" is defined.
 +
 +
Every object is an instance of a class. And every instance of a class is an object. You can basically interchange these.
 +
 +
You have 5 apples in your basket. Each of those apples is an object of type Apple, which has some characteristics (i.e. big, round, grows on trees).
 +
 +
In programming terms, you can have a class called Apple, which has variables size:big, shape:round, habitat:grows on trees. To have 5 apples in your basket, you need to instantiate 5 apples. Apple apple1, Apple apple2, Apple apple3 etc....
 +
 +
Alternatively: Objects are the definitions of something, instances are the physical things.
  
 
==Variables==
 
==Variables==

Revision as of 21:26, 6 April 2018

Class vs Object vs Instance

https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/

In OO Programming, we often hear of terms like "Class", "Object" and "Instance"; but what actually is a Class / Object / Instance?

In short, An object is a software bundle of related state and behavior. A class is a blueprint or prototype from which objects are created. An instance is a single and unique unit of a class.

Example, we have a blueprint (class) represents student (object) with fields like name, age, course (class member). And we have 2 students here, Foo and Bob. So, Foo and Bob is 2 different instances of the class (Student class) that represent object (Student people).

Let me go into details...

Object

Real world objects shares 2 main characteristics, state and behavior. Human have state (name, age) and behavior (running, sleeping). Car have state (current speed, current gear) and state (applying brake, changing gear). Software objects are conceptually similar to real-world objects: they too consist of state and related behavior. An object stores its state in fields and exposes its behavior through methods.

Class

Class is a “template” / “blueprint” that is used to create objects. Basically, a class will consists of field, static field, method, static method and constructor. Field is used to hold the state of the class (eg: name of Student object). Method is used to represent the behavior of the class (eg: how a Student object going to stand-up). Constructor is used to create a new Instance of the Class.

Instance

An instance is a unique copy of a Class that representing an Object. When a new instance of a class is created, the JVM will allocate a room of memory for that class instance.

Otro punto de vista

Luego de leer distintos fuentes para tratar de entender los conceptos de «Class vs Object vs Instance» me ha parecido que los conceptos de «Object and Instance» no están bien diferenciados... es decir no encuentro una definición que verdaderamente me convenza de la diferencia entre estos dos conceptos.

Entonces, encontré otra fuente que plantea lo siguiente: https://www.javatpoint.com/q/3420/difference-between-instance-and-object-?

Object and Instance are the same thing in most object-oriented languages. "Instance of a class" is just how the term "object" is defined.

Every object is an instance of a class. And every instance of a class is an object. You can basically interchange these.

You have 5 apples in your basket. Each of those apples is an object of type Apple, which has some characteristics (i.e. big, round, grows on trees).

In programming terms, you can have a class called Apple, which has variables size:big, shape:round, habitat:grows on trees. To have 5 apples in your basket, you need to instantiate 5 apples. Apple apple1, Apple apple2, Apple apple3 etc....

Alternatively: Objects are the definitions of something, instances are the physical things.

Variables

  • Holder for information
  • Not a fixed value, contents can be changed
  • Every variable has a type

Types of variables (clasificación 1)

Type can be:

  • Primitive
  • Object

Primitive - Simple data type

  • E.g. int, double, char, boolean
  • Built into Java
  • Can only hold one piece of data of a specific type
  • All begin with a lowercase letter

Object - Complex data type

  • Created based on classes. These can be either built into Java (E.g. Scanner, String, ArrayList) or user-defined (e.g. Item)
  • Can hold multiple pieces of data of different types
  • All begin with an uppercase letter

Variables in Memory

  • Primitive in memory:
    • Actual data is stored within variable
      • E.g. int num = 78;
Primitive in memory1.png
  • When you change a primitive variable, the value inside the variable changes:
  • E.g. int x = 12;
  • num = x;
Primitive in memory2.png
  • Object in memory:
    • Variable contains a reference to the location where the data is stored.
      • E.g. Item item = new Item(“Bread”, 2.50, 1);
Object in memory1.png
  • When you change information inside an object, the value (reference) inside the variable stays the same.
  • E.g. item.setName("apple"); (Es decir, aquí estoy cambiando la data (la información que se encuentra en la dirección indicada por la variable) pero lo que en realidad es el «valor de la variable» es la referencia (la dirección que indica (o que referencia) la data)).
  • When you change an object variable, you change the reference:
Object in memory2.png

Types of variables (clasificación 2)

Instance variable

Instance variables are declared in a class, but outside a method, constructor or any block.

For each instantiated object of the class, a separate copy of each instance variables (or instance) is made.

Four fundamental OOP concepts

  • Encapsulation
  • Inheritance
  • Polymorphism
  • Abstraction

Encapsulation

Encapsulation in Java is a mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit. In encapsulation the variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class, therefore it is also known as data hiding.

To achieve encapsulation in Java:

  • Declare the variables of a class as private.
  • Provide public setter and getter methods to modify and view the variables values.
TestEncapsulation.java
public class TestEncapsulation{
    
    private String name;
    private String idNum;
    private int age;
   
    public int getAge(){
        return age;
    }
    
    public String getName(){
        return name;
    }
    
    public String getIdNum(){
        return idNum;
    }
    
    public void setAge(int newAge){
        age = newAge;
    }
    
    public void setName(String newName){
        name = newName;
    }
    
    public void setIdNum(String newId){
        idNum = newId;
    }
    
}

The public setXXX() and getXXX() methods are the access points of the instance variables of the TestEncapsulation class. Normally, these methods are referred as getters and setters. Therefore any class that wants to access the variables should access them through these getters and setters.

The variables of the EncapTest class can be accessed as below:

/* File name : RunEncapsulation.java */

public class RunEncapsulation{
    public static void main(String args[]){
        TestEncapsulation encap = new TestEncapsulation();
        encap.setName("James");
        encap.setAge(20);
        encap.setIdNum("12343ms");
        
        System.out.print("Name : " + encap.getName() + " Age : " + encap.getAge());
    }
}

This would produce the following result:

Name : James Age : 20

Benefits of Encapsulation:

  • The fields of a class can be made read-only or write-only.
  • A class can have total control over what is stored in its fields.
  • The users of a class do not know how the class stores its data. A class can change the data type of a field and users of the class do not need to change any of their code.

Inheritance

Inheritance can be defined as the process where one class acquires the properties (methods and fields) of another. With the use of inheritance the information is made manageable in a hierarchical order.

The class which inherits the properties of other is known as subclass (derived class, child class) and the class whose properties are inherited is known as superclass (base class, parent class).


extends keyword

extends is the keyword used to inherit the properties of a class. With use of the extends keyword the subclasses will be able to inherit all the properties of the superclass except for the private properties of the superclass.

Example:

class Super{
    ...
    ...
}


class Sub extends Super{
    ...
    ...
}
Calculation.java
package calculation;

class Calculation {
    int z;
    
    public void addition(int x, int y){
        z=x+y;
        System.out.println("The sum of the given numbers:"+z);
    }
    
    public void substraction(int x,int y){
        z=x-y;
        System.out.println("The difference between the given numbers:"+z);
    }
}
MyCalculation.java
package calculation;

public class MyCalculation extends Calculation{
    
    public void multiplication(int x, int y){
        z = x*y;
        System.out.println("The product of the given numbers is: "+z);
    }
    
    public static void main(String args[]){
        int a=20, b=10;
        MyCalculation demo = new MyCalculation();
        demo.addition(a,b);
        demo.substraction(a, b);
        demo.multiplication(a, b);
    }
}

Using extends keyword, My_Calculation inherits the methods addition() and Subtraction() from Calculation class.

You can instantiate the class as given below as well. But using the superclass reference variable ( cal in this case ) you cannot call the method multiplication(), which belongs to the subclass My_Calculation:

Calculation cal = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

The super keyword

The super keyword is similar to this keyword. The following are the scenarios where the super keyword is used.

  • It is used to differentiate the members of superclass from the members of subclass, if they have same names.
  • It is used to invoke the superclass constructor from subclass.
Differentiating the members

If a class is inheriting the properties of another class, and if the members of the superclass have the same names as the sub class, to differentiate these variables we use super keyword as shown below.

super.variable
super.method();


Sample Code

In the given program you have two classes namely Sub_class and Super_class, both have a method named display() with different implementations, and a variable named num with different values.


package btest2_the_super_keyword;

class Super_class{
    int num=20;

    //display method of superclass
    public void display(){
        System.out.println("This is the display method of superclass");
    }
}
package btest2_the_super_keyword;

public class Sub_class extends Super_class {
    int num=10;
    
    //display method of sub class
    public void display(){
        System.out.println("This is the display method of subclass");
    }
    
    public void my_method(){
        //Instantiating subclass
        Sub_class sub=new Sub_class();
        
        //Invoking the display() method of sub class
        sub.display();
        
        //Invoking the display() method of superclass
        super.display();
        
        //printing the value of variable num of subclass
        System.out.println("value of the variable named num in sub class:"+ sub.num);
        
        //printing the value of variable num of superclass
        System.out.println("value of the variable named num in super class:"+ super.num);
        
    }

    public static void main(String args[]){
        Sub_class obj = new Sub_class();
        obj.my_method();
    }
    
}
Invoking Superclass constructor

If a class is inheriting the properties of another class, the subclass automatically acquires the default constructor of the super class. But if you want to call a parameterized constructor of the super class, you need to use the super keyword as shown below.

super(values);
class SuperClass{
    
    int age;
    
    SuperClass(int age){
        this.age=age;
    }
    
    public void getAge(){
        System.out.println("The value of the variable named age in super class is: " +age);
    }
}
public class SubClass extends SuperClass {
    
    SubClass(int age){
        super(age);
    }
    
    public static void main(String argd[]){
        SubClass s = new SubClass(24);
        s.getAge();
    }
    
}

IS-A relationship

IS-A is a way of saying : This object is a type of that object.

public class Animal{

}

public class Mammal extends Animal{

}

public class Reptile extends Animal{

}

public class Dog extends Mammal{
    public static void main(String args[]){
        Animal a = new Animal();
        Mammal m = new Mammal();
        Dog    d = new Dog();

        System.out.println(m instanceof Animal); // true
        System.out.println(d instanceof Mammal); // true
        System.out.println(d instanceof Animal); // true
    }

}

The following are true:

  • Animal is the superclass of Mammal class.
  • Animal is the superclass of Reptile class.
  • Mammal and Reptile are subclasses of Animal class.
  • Dog is the subclass of both Mammal and Animal classes.

Now, if we consider the IS-A relationship, we can say:

  • Mammal IS-A Animal
  • Reptile IS-A Animal
  • Dog IS-A Mammal
  • Therefore : Dog IS-A Animal as well

HAS-A relationship

These relationships are mainly based on the usage. This determines whether a certain class HAS-A certain thing. This relationship helps to reduce duplication of code as well as bugs.

public class Vehicle{} 

public class Speed{} 

public class Van extends Vehicle{
    private Speed sp;
}

This shows that class Van HAS-A Speed. By having a separate class for Speed, we do not have to put the entire code that belongs to speed inside the Van class. We also can reuse the Speed class in multiple applications.

Types of inheritance

Types of inheritance

A very important fact to remember is that Java does not support multiple inheritance. This means that a class cannot extend more than one class. Therefore following is illegal:

public class extends Animal, Mammal{} // Illegal in Java

However, a class can implement one or more interfaces. This has made Java get rid of the impossibility of multiple inheritance.

Polymorphism

Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.

Any Java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all Java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object.

It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared, the type of a reference variable cannot be changed.

The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object.

Let us look at an example:

public interface Vegetarian{}

public class Animal{}

public class Deer extends Animal implements Vegetarian{}

The Deer class is considered to be polymorphic since this has multiple inheritance. The following are true for the above example:

  • A Deer IS-A Animal
  • A Deer IS-A Vegetarian
  • A Deer IS-A Deer
  • A Deer IS-A Object

When we apply the reference variable facts to a Deer object reference, the following declarations are legal:

Deer d = new Deer();

Animal a = d;

Vegetarian v = d;

Object o = d;

All the reference variables d,a,v,o refer to the same Deer object in the heap.

Virtual Methods

The behaviour of overridden methods in Java allows you to take advantage of polymorphism when designing your classes.

Method overriding, where a child class can override a method in its parent. An overridden method is essentially hidden in the parent class, and is not invoked unless the child class uses the super keyword within the overriding method.

package virtualmethods;

public class Employee {
    
    private String name;
    private String address;
    private int    number; 
    
    public Employee(String name, String address, int number) { 
        System.out.println("Constructing an Employee"); 
        this.name    = name; 
        this.address = address; 
        this.number  = number; 
    } 
    
    public void mailCheck() { 
        System.out.println("Mailing a check to "+ this.name + " "+ this.address);
    }
    
    public String toString() { 
        return name + " " + address + " " + number; 
    } 
    
    public String getName() { 
        return name; 
    } 
    
    public String getAddress() { 
        return address; 
    } 
    
    public void setAddress(String newAddress) {
        address = newAddress; 
    } 
    
    public int getNumber() {
        return number; 
    }
    
}
package virtualmethods;

public class Salary extends Employee {
    
    private double salary;
    
    public Salary(String name, String address, int number, double salary) { 
        super(name, address, number);
        setSalary(salary);
    } 
    
    public void mailCheck() {
        System.out.println("Within mailCheck of Salary class ");
        System.out.println("Mailing check to "+getName()+ " with salary "+salary);
    }
    
    public double getSalary() {
        return salary;
    }
    
    public void setSalary(double newSalary){
        if(newSalary >= 0.0){
            salary = newSalary;
        }
    }
    
    public double computePay(){
        System.out.println("Computing salary pay for " + getName());
        return salary/52;
    }
    
}
package virtualmethods;

public class VirtualDemo {
    public static void main(String [] args){
        
        Salary   s = new Salary("Joe Bloggs", "Dublin 10", 3, 3600.00);
        Employee e = new Salary("John Adams", "Dublin 12", 2, 2400.00);
        
        System.out.println("\nCall mailCheck using Salary reference:");        
        s.mailCheck();
        
        System.out.println("\nCall mailCheck using Employee reference:");
        e.mailCheck();
        
    }
    
}

This would produce the following result:

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference:
Within mailCheck of Salary class 
Mailing check to Joe Bloggs with salary 3600.0

Call mailCheck using Employee reference:
Mailing a check to John Adams Dublin 12

Here, we instantiate two Salary objects . one using a Salary reference s, and the other using an Employee reference e. While invoking s.mailCheck() the compiler sees mailCheck() in the Salary class at compile time, and the JVM invokes mailCheck() in the Salary class at run time.

Invoking mailCheck() on e is quite different because e is an Employee reference. When the compiler sees e.mailCheck(), the compiler sees the mailCheck() method in the Employee class.

Here, at compile time, the compiler used mailCheck() in Employee to validate this statement. At run time, however, the JVM invokes mailCheck() in the Salary class.

This behavior is referred to as virtual method invocation, and the methods are referred to as virtual methods. All methods in Java behave in this manner, whereby an overridden method is invoked at run time, no matter what data type the reference is, which was used in the source code at compile time.

Abstraction

As per the dictionary, Abstraction is the quality of dealing with ideas rather than events. For example when you consider the case of e-mail, complex details such as what happens when you send an e-mail, the protocol your email server uses are hidden from the user, therefore to send an e-mail you just need to type the content, mention the address of the receiver and click send.

likewise in Object oriented programming Abstraction is a process of hiding the implementation details from the user, only the functionality will be provided to the user. In other words user will have the information on what the object does instead of how it does it.

In Java Abstraction is achieved using Abstract classes, and Interfaces.

Abstract Class

A class which contains the abstract keyword in its declaration is known as abstract class.

  • Abstract classes may or may not contain abstract methods ie., methods without a body.
    • Un «abstract method» is un método que sólo está declarado. No contiene más nada: public void get();
  • But, if a class has at least one abstract method, then the class must be declared abstract.
  • If a class is declared abstract it cannot be instantiated.
  • To use an abstract class you have to inherit it from another class, provide implementations to the abstract methods in it.
  • If you inherit an abstract class you have to provide implementations to all the abstract methods in it.

Example:

package atest1;

public abstract class Employee {
    
    private String name;
    private String address;
    private int    number;
    
    public Employee(String name, String address, int number){
        System.out.println("Constructing an Employee");
        this.name    = name;
        this.address = address;
        this.number  = number;
    }
    
    public double computePay(){
        System.out.println("Inside Employee computePay");
        return 0.0;
    }
    
    public void mailCheck(){
        System.out.println("Mailing a check to " + this.name + " " + this.address);
    }
    
    public String toString(){
        return name + " " + address + " " + number;
    }
    
    public String getName(){
        return name;
    }
    
    public String getAddress(){
        return address;
    }
    
    public void setAddress(String newAddress){
        address = newAddress;
    }
    
    public int getNumber(){
        return number;
    }
            
}

You can observe that except abstract methods the Employee class is same as normal class in Java. The class is now abstract, but it still has three fields, seven methods, and one constructor.

Now you can try to instantiate the Employee class as shown below:

package atest1_abstract_class;

public class AbstractDemo {
    
    public static void main(String [] args){
        // Following is not allowed and would raise the error:
        // Employee.java:46: Employee is abstract; cannot be instantiated
        // Employee e = new Employee("George W.", "Houston, TX", 43);
        
        // Esto no s'e que es. Netbeans me da la opci'on de instanciar esta abstract class as'i:
        Employee e = new Employee("George W.", "Houston, TX", 43) {};
        
        System.out.println("\n Call mailCheck using Employee reference:");
        e.mailCheck();
        
    }
    
}

When you compile the above class, it gives you the following error:

Employee.java:46: Employee is abstract; cannot be instantiated
    Employee e = new Employee("George W.", "Houston, TX", 43);
Inheriting the Abstract Class

We can inherit the properties of Employee class just like concrete class as shown below:

package atest1_abstract_class;

public class Salary extends Employee{
    
    private double salary;
    
    public Salary(String name, String address, int number, double salary){
        super(name, address, number);
        setSalary(salary);
    }
    
    public void mailCheck(){
        System.out.println("Within mailCheck of Salary class ");
        System.out.println("Mailing check to " + getName() + " with salary " + salary);
    }
    
    public double getSalary(){
        return salary;
    }
    
    public void setSalary(double newSalary){
        if(newSalary >= 0.0){
            salary = newSalary;
        }
    }
    
    public double computePay(){
        System.out.println("Computing salary pay for " + getName());
        return salary/52;
    }
}

Here, you cannot instantiate the Employee class, but you can instantiate the Salary Class, and using this instance you can access the all the three fields and seven methods of Employee class as shown below.

package atest1_abstract_class;

public class AbstractDemo {
    
    public static void main(String [] args){  
        Salary   s  = new Salary("Joe Bloggs", "Dublin 10", 3, 3600.00);
        Employee e2 = new Salary("John Adams", "Dublin 12", 2, 2400.00);
        
        System.out.println("\nCall mailCheck using Salary reference:");
        s.mailCheck();
        
        System.out.println("\nCall mailCheck using Employee reference--");
        e.mailCheck();
        
    }
    
}

This produces the following result:

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference:
Within mail Check of Salary class
Mailing check to Joe Bloggs with salary 3600.0

Call mail Check using Employee reference:
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.00

Abstract Methods

If you want a class to contain a particular method but you want the actual implementation of that method to be determined by child classes, you can declare the method in the parent class as abstract.

  • Abstract keyword is used to declare the method as abstract.
  • You have to place the abstract keyword before the method name in the method declaration.
  • An abstract method contains a method signature, but no method body.
public abstract class Employee{

    private String name;
    private String address;
    private int number;

    public abstract double computePay();

    // Remainder of class definition

}

Declaring a method as abstract has two consequences:

  • The class containing it must be declared as abstract.
  • Any class inheriting the current class must either override the abstract method or declare itself as abstract.

Suppose Salary class inherits the Employee class, then it should implement the computePay() method as shown below:

public class Salary extends Employee {
    private double salary;
    public double computePay() {
        System.out.println("Computing salary pay for " + getName());
        return salary/52;
    }

    // Remainder of class definition

}