Java. Перевантаження методів у класах. Перевантаження конструкторів

Java. Перевантаження методів у класах. Перевантаження конструкторів


Зміст


1. У чому полягає суть перевантаження методів у мові програмування Java? Приклад

Під поняттям “перевантаження” розуміється використання одного й того ж імені методу декілька разів при його оголошенні у класі. З точки зору синтаксису мови, не може бути двох однакових імен у деякому локальному просторі. Однак, допускається оголошення методів (функцій) з однаковими іменами але відмінними (різними) параметрами. Якщо викликається перевантажений метод, то з декількох оголошених методів, компілятор автоматично визначає потрібний за його параметрами, що вказуються при виклику.

Перевантаження методів є ефективним механізмом реалізації поліморфізму у класах.

В загальному, оголошення класу, що містить перевантажений метод, може виглядати так:

class CMyClass
{

    // ...
    OverloadedMethod(parameters1)
    {
        // ...
    }

    OverloadedMethod(parameters2)
    {
        // ...
    }

    // ...

    OverloadedMethod(parametersN)
    {
        // ...
    }
}

де

  • CMyClass – ім’я класу;
  • OverloadedMethod1() – ім’я перевантаженого методу;
  • parameters1, parameters2, …, parametersN – параметри (список параметрів) кожного з перевантажених методів. Ці параметри обов’язково мають відрізнятись між собою типами або кількістю.

2. Приклад класу, що містить перевантажені методи

У прикладі оголошується клас Complex, що реалізує комплексне число, яке складається з дійсної та уявної частини. У класі реалізовано:

  • внутрішні змінні дійсного типу з іменами a, b. Ці змінні відповідають дійсній та уявній частині числа: z = a+bi;
  • конструктор класу Complex() без параметрів;
  • методи доступу GetA(), GetB(), SetComplex();
  • перевантажений метод Mult(), що реалізує різні варіанти множення комплексного числа, реалізованого у класі.

Текст оголошення класу

public class Complex
{
    // приховані дані класу
    private double a; // дійсна частина
    private double b; // уявна частина

    // конструктор класу
    Complex()
    {
        a = 1;
        b = 1;
    }

    // методи доступу
    double GetA() { return a; }
    double GetB() { return b; }

    void SetComplex(double a, double b) // для типу double
    {
        this.a = a;
        this.b = b;
    }

    // Перевантажений метод Mult()
    // без параметрів - піднесення до квадрату
    Complex Mult()
    {
        Complex c = new Complex();
        double A, B;

        A = a*a - b*b;
        B = a*b + b*a;
        c.SetComplex(A, B);

        return c;
    }

    // метод Mult() з 1 параметром - множення комплексного числа на число
    Complex Mult(double d)
    {
        Complex c = new Complex();
        double A, B;

        A = a*d;
        B = b*d;
        c.SetComplex(A, B);

        return c;
    }

    // метод Mult() з 2 параметрами - множення комплексних чисел
    Complex Mult(double a2, double b2)
    {
        Complex c = new Complex();
        double A, B;

        A = a*a2 - b*b2;
        B = a*b2 + b*a2;
        c.SetComplex(A, B);

        return c;
    }
}

Використання класу в іншому методі

...

Complex c1 = new Complex();
double A, B;

c1.SetComplex(2.0, 3.0);

// використання перевантаженого методу Mult()
Complex c2 = c1.Mult(); // піднесення до квадрату

A = c2.GetA(); // A = -5.0
B = c2.GetB(); // B = 12.0

c2 = c1.Mult(4); // множення на число
A = c2.GetA(); // A = 8.0
B = c2.GetB(); // B = 12.0

c2 = c1.Mult(1, 3); // множення на комплексне число
A = c2.GetA(); // A = -7.0
B = c2.GetB(); // B = 9.0

...

3. За якими ознаками параметри перевантажених методів відрізняються між собою?

 Якщо ім’я методу перевантажено, то параметри цього методу можуть відрізнятись:

  • кількістю параметрів;
  • типами параметрів, що отримує метод.

 



4. Скільки методів може бути перевантажено у класі?

У класі може бути перевантажено будь-яка кількість методів.

5. Скільки перевантажених реалізацій може мати метод у класі?

У класі перевантажений метод може мати будь-яку кількість реалізацій. Головне, щоб сигнатура списку параметрів кожного перевантаженого методу була унікальною.

6. Яким чином реалізується перевантаження конструкторів у класі? Приклад

Перевантаження конструкторів реалізується так само, як і перевантаження методів. Перевантаження конструкторів дозволяє встановити різні способи початкової ініціалізації об’єктів класу.

Нижче наведено клас Circle, що реалізує коло. У класі реалізуються наступні змінні екземпляру класу та методи:

  • приховані (private) змінні x, y, r, що визначають координати центру кола та його радіус;
  • чотири перевантажені конструктори;
  • методи доступу до зовнішніх змінних класу GetCircle(), GetX(), GetY(), GetR(), SetXYR();
  • метод, що обчислює площу кола GetSquare().

Програмний код класу наступний

public class Circle 
{
    // клас, що реалізує коло на координатній площині
    private int x, y; // координати центру кола
    private int r; // радіус кола

    // перевантажені конструктори
    // конструктор без параметрів
    Circle()
    {
        x = y = 0;
        r = 1;
    }

    // конструктор з 1 параметром
    Circle(int r)
    {
        this.r = r;
    }

    // конструктор з 2 параметрами
    Circle(int x, int y)
    {
        this.x = x;
        this.y = y;
        r = 1;
    }

    // конструктор з 3 параметрами
    Circle(int x, int y, int r)
    {
        this.x = x;
        this.y = y;
        this.r = r;
    }

    // методи доступу
    // повертає коло
    Circle GetCircle()
    {
        // створити новий об'єкт типу Circle, обов'язково виділити пам'ять для нього
        Circle c = new Circle(x, y, r);
        return c;    // повернути об'єкт
    }

    // повернути координати і радіус
    int GetX() { return x; }
    int GetY() { return y; }
    int GetR() { return r; }

    // встановити нові значення x, y, r
    int SetXYR(int nx, int ny, int nr)
    {
        x = nx;
        y = ny;
        r = nr;
    }

    // метод, що обчислює площу круга
    double GetSquare()
    {
        return (double)(3.1415*r*r);
    }
}

Використання класу в іншому програмному коді

// використання класу Circle в іншому програмному коді
Circle c0 = new Circle(); // виклик конструктора без параметрів
Circle c1 = new Circle(5); // виклик конструктора з 1 параметром
Circle c2 = new Circle(20, 15); // виклик конструктора з 2 параметрами
Circle c3 = new Circle(10, 8, 5); // виклик конструктора з 3 параметрами
int d;

// перевірка
d = c0.GetR(); // d = 1
d = c1.GetX(); // d = 0
d = c2.GetY(); // d = 15
d = c3.GetR(); // d = 5

double s = c3.GetSquare(); // s = 62.830000000000005

У вищенаведеному коді перевантажується 4 конструктори:

// конструктор без параметрів
Circle()
{
    // ...
}

// конструктор з 1 параметром
Circle(int r)
{
    // ...
}

// конструктор з 2 параметрами
Circle(int x, int y)
{
    // ...
}

// конструктор з 3 параметрами
Circle(int x, int y, int r)
{
    // ...
}

Ці конструктори відрізняються різною кількістю параметрів.

7. Чи можна в класі оголосити два методи, які мають однакові сигнатури вхідних параметрів, але які повертають різні типи значень? Приклад

Так, можна. Нижченаведений приклад демонструє використання перевантаженого методу GetD(), який не отримує параметрів, але повертає різні типи значень (int, double).

Оголошується клас Demo, в якому реалізовані:

  • внутрішня змінна d;
  • перевантажений метод доступу GetD() без параметрів, що повертає різні типи значень.

Текст класу:

public class Demo
{
    private int d;

    // конструктор класу
    Demo()
    {
        d = 0;
    }

    // методи доступу
    int GetD() { return d; }
    double GetD() { return (double)d; }

    void SetD(int nd) { d = nd; }
}

Демонстрація використання методу GetD() класу Demo в іншому програмному коді

Demo d1 = new Demo();
int t;
double x;

d1.SetD(8);

t = d1.GetD(); // t = 8 - викликається: int GetD()
x = d1.GetD(); // x = 8.0 - викликається: double GetD()


Зв’язані теми