SE_21_Lesson_6: Class and Objects

Class definition: 

-> A class — in the context of Java — is a template used to create objects and to define object data types and methods.

A class in Java is a logical template to create objects that share common properties and methods.

 

Object definition:

-> A Java object is a member (also called an instance) of a Java class. Each object has an identity, a behavior(methods) and a state(fields).

The state of an object is stored in fields (variables), while methods (functions) display the object's behavior. Objects are created at runtime from templates, which are also known as classes.



Variables:

1. Object variables (instance or state or field): 

Funksional olaraq obyektin ozelliklerini ifade edir.

Object variables hem primitive ham de reference deyishenler ola biler.

Local variable-lardan ferqli olaraq, Object variable - larin default deyerleri movcuddur. Mes:

package org.example;

public class Car {
public String make;
public String model;
public String year;
public int speed;
public int distance;

public void go(int newDistance) {

}

public void accelerate(int newSpeed) {

}

public void stop() {

}

@Override
public String toString() {
return "Car{" +
"make='" + make + '\'' +
", model='" + model + '\'' +
", year='" + year + '\'' +
", speed=" + speed +
", distance=" + distance +
'}';
}
}
package org.example;

public class Main {
public static void main(String[] args) {
Car car = new Car();
System.out.println(car);
}
}


-> Illegal forward reference 

package org.example;

public class Apartment {
public static int wall = door;
public static int door;

public static int window = painting;
public int painting;
}



package org.example;

public class Apartment {
public int wall = door;
public static int door = 5;
}



-> Null. Assigning null to an object(assigning null to a variable(pointer)), then assigning null to static and non-static fields

package org.example;

public class Student {
public static int count;
public String name;
}
package org.example;

public class Lesson6 {
public static void main(String[] args) {
Student student = null;
student.count = 5;
System.out.println(student.count);
System.out.println(Student.count);
}
}



-> null anlayishi. Deyishene(obyekte) null menimsetmek ve sonra hemin deyihenin(obyektin) non-static fieldlarina deyer menimsetmek ve static fieldlarina deyer menimsetmek

package org.example;

public class Student {
public static String name;
public String gender;
}
package org.example;

public class Main {
public static void main(String[] args) {
Student student = null;
student.name = "alibaba";

System.out.println(student.name);

student.gender = "male";
System.out.println(student.gender);
}
}


-> Muxtelif deyishenlerin eyni obyekte referans etmesi. Her iki obyektin non-static(instance) ve static(class) variable-nin deyishdirilmesi ve obyektlerin bir birine menimsedilmesi.

package org.example;

public class Test {
public int age;
public static int year;
}
package org.example;

public class Main {
public static void main(String[] args) {
Test test = new Test();
test.age = 1;
test.year = 1;

Test test1 = new Test();
test1.age = 2;
test1.year = 2;

test1 = test;

System.out.println(test.age);
System.out.println(test1.age);
System.out.println("-----------------------------------------------");
System.out.println(test.year);
System.out.println(test1.year);
}
}


-> Referanslarin qirilmasi

Student student = new Student(); // 1234
student.gender = "male";

student = new Student(); // 1235
System.out.println(student.gender);


-> Pass by value and pass by reference principle

package org.example;

public class Main {
public static void main(String[] args) {
int i = 5;
System.out.println(i);
foo(i);
System.out.println(i);

Student one = new Student();
one.gender = "male";
System.out.println(one.gender);
foo2(one);
System.out.println(one.gender);

int[] arr = {1, 2, 3};
System.out.println(arr[0]);
foo3(arr);
System.out.println(arr[0]);
}

public static void foo(int a) {
a++;
}

public static void foo2(Student student) {
student.gender = "female";
}

public static void foo3(int[] arr) {
arr[0]++;
}
}



-> Klasin icinde obyekt. Has-a relationship

Composite or aggregate objects:

package org.example;

public class Car {
public String make;
public String model;
public String year;
public int speed;
public int distance;
public Person owner;

public void go(int newDistance) {
distance += newDistance;
}

public void accelerate(int newSpeed) {
speed = newSpeed;
}

public void stop() {
speed = 0;
}

@Override
public String toString() {
return "Car{" +
"make='" + make + '\'' +
", model='" + model + '\'' +
", year='" + year + '\'' +
", speed=" + speed +
", distance=" + distance +
", owner=" + owner.name +
'}';
}
}
package org.example;

public class Person {
public String pin;
public String name;
public String surname;
public Car vehicle;

@Override
public String toString() {
return "Person{" +
"pin='" + pin + '\'' +
", name='" + name + '\'' +
", surname='" + surname + '\'' +
", vehicle=" + vehicle +
'}';
}
}
package org.example;

public class Main {
public static void main(String[] args) {
Person ali = new Person();
ali.pin = "abc123";
ali.name = "Ali";
ali.surname = "Aliyev";

Car cadillac = new Car();
cadillac.make = "Cadillac";
cadillac.model = "escalade";
cadillac.year = "2023";
cadillac.speed = 100;
cadillac.distance = 20000;
cadillac.owner = ali;

ali.vehicle = cadillac;

System.out.println(ali);
System.out.println("----------------------------------");
System.out.println(cadillac);
}
}

Burada one-to-one relationship qurulub. Bidirectional association.


-> Static filed-lara en gozel numune olaraq. Math.PI, Math.E, Integer.MAX_VALUE

int maxValue = Integer.MAX_VALUE;
System.out.println(maxValue);
double pi = Math.PI;
System.out.println(pi);



--------------------------------------------------------------------------------------------------------------------------------


Relationships between Classes

The most common relationships between classes are

  • Dependence (“uses–a”)

  • Aggregation (“has–a”)

  • Inheritance (“is–a”)

1. Dependence (“uses–a”)

Dependence implies that one class uses another class. It is a weaker relationship compared to aggregation and inheritance. This relationship is usually transient and happens when one class calls the methods of another class to perform some task.

class Engine {

    void start() {

        System.out.println("Engine started");

    }

}


class Car {

    private Engine engine;


    Car() {

        this.engine = new Engine();

    }


    void drive() {

        engine.start();

        System.out.println("Car is driving");

    }

}


public class Main {

    public static void main(String[] args) {

        Car car = new Car();

        car.drive();

    }

}

In this example, the Car class depends on the Engine class. The Car uses the Engine to start the car.


2. Aggregation (“has–a”)

Aggregation implies a “has–a” relationship where one class contains another class. Aggregation represents a whole-part relationship, but the part can exist independently of the whole.

class Engine {

    void start() {

        System.out.println("Engine started");

    }

}


class Car {

    private Engine engine;


    Car(Engine engine) {

        this.engine = engine;

    }


    void drive() {

        engine.start();

        System.out.println("Car is driving");

    }

}


public class Main {

    public static void main(String[] args) {

        Engine engine = new Engine();

        Car car = new Car(engine);

        car.drive();

    }

}

In this example, the Car class has an Engine object, representing an aggregation relationship. The Engine can exist independently of the Car.

3. Inheritance (“is–a”)

Inheritance implies an “is–a” relationship where one class inherits the properties and behaviors of another class. This allows for reuse of existing code and can be represented with the extends keyword in Java.

class Vehicle {

    void start() {

        System.out.println("Vehicle started");

    }

}


class Car extends Vehicle {

    void drive() {

        System.out.println("Car is driving");

    }

}


public class Main {

    public static void main(String[] args) {

        Car car = new Car();

        car.start(); // Inherited method from Vehicle

        car.drive();

    }

}

In this example, the Car class inherits from the Vehicle class. This means that Car is a Vehicle and can use the start method defined in the Vehicle class.



======================================================================================================================================================

                                                                                ***


The reason the reference of test does not change outside of the foo() method lies in how Java handles method arguments and object references.

In Java, when you pass an object to a method, you are passing the reference to that object (i.e., the memory address where the object is stored). However, the reference itself is passed by value, meaning that the method gets a copy of the reference, not the original reference itself.

Breakdown of the code:

  1. Before calling foo():

    • You create a new Test object and assign it to the variable test.
    • You set test.name = "Parvin", so the test object now has the name "Parvin".
  2. Inside foo():

    • You pass the test object to the method foo().
    • Inside the method, you create a new Test object, test2, and set test2.name = "Parvin2".
    • Then, you assign test2 to test. This means that the local reference variable test (inside the foo() method) now points to the test2 object. However, this does not affect the original reference outside of the method.

    Why? Because the reference to test inside foo() is a copy of the reference passed in. When you modify test to point to test2, you're changing the local copy of the reference, not the original reference outside the method.

  3. After calling foo():

    • The test object outside foo() still points to the original object (which has the name "Parvin").
    • Therefore, when you print test again after the method call, it still has the name "Parvin".

Example:

Here’s a modified version of your code with comments explaining the steps:

class Test {
    String name;

    public String toString() {
        return "Test{name='" + name + "'}";
    }
}

public class Main {
    public static void main(String[] args) {
        Test test = new Test();  // Create a new Test object
        test.name = "Parvin";    // Set its name to "Parvin"
        System.out.println(test); // Prints: Test{name='Parvin'}

        foo(test);               // Pass test to the foo() method
        System.out.println(test); // Prints: Test{name='Parvin'} (no change)
    }

    public static void foo(Test test) {
        Test test2 = new Test(); // Create a new Test object
        test2.name = "Parvin2";  // Set its name to "Parvin2"

        test = test2;            // Change the local reference 'test' to point to 'test2'
    }
}

Output:

Test{name='Parvin'}
Test{name='Parvin'}

To Modify the Original Object:

If you want to modify the original test object inside foo(), you can change its fields (not the reference). Here's an updated version that works:

public static void foo(Test test) {
    test.name = "Parvin2";  // Modify the object's field, not the reference
}

In this case, the name of the original test object will change to "Parvin2".

Updated Output:

Test{name='Parvin'}
Test{name='Parvin2'}

Summary:

  • Java passes object references by value, meaning that you cannot change the reference itself in the calling method, but you can modify the object's fields.
  • If you want to modify the object reference itself in the calling method, you'd need to return a new reference or work with the reference in a way that affects the caller, such as using a container object (like a list or array).






Комментарии

Популярные сообщения из этого блога

Lesson1: JDK, JVM, JRE

Lesson_4: Control flow