Temat C11. Stosowanie metod w języku Java

przez | 5 listopada 2022

Wszystkie treści na stronie ir.migra.pl chronione są prawami autorskimi. Więcej informacji znajdziesz tutaj.

Uwaga: Zapoznaj się wcześniej z tematem C2 z podręcznika „Teraz bajty. Informatyka dla szkół ponadpodstawowych. Zakres podstawowy. Klasa II” albo z tematami 61-62 z podręcznika „Informatyka 1-3. Podręcznik dla szkół ponadpodstawowych. Zakres podstawowy.”. Wykonaj zawarte tam ćwiczenia i zadania.

Zapisy podstawy programowej realizowane w temacie:

I. Rozumienie, analizowanie i rozwiązywanie problemów.

Zakres rozszerzony. Uczeń spełnia wymagania określone dla zakresu podstawowego, a ponadto:

  1. w zależności od problemu rozwiązuje go, stosując metodę wstępującą lub zstępującą;
  2. do realizacji rozwiązania problemu dobiera odpowiednią metodę lub technikę algorytmiczną i struktury danych;
  3. II. Programowanie i rozwiązywanie problemów z wykorzystaniem komputera i innych urządzeń cyfrowych.
    Zakres rozszerzony. Uczeń spełnia wymagania określone dla zakresu podstawowego, a ponadto:

  4. sprawnie posługuje się zintegrowanym środowiskiem programistycznym przy pisaniu, uruchamianiu i testowaniu programów;

Spis treści

  1. Metody w języku Java
  2. Dostęp do metod, pól i klas
  3. Deklaracja metody
    1. Wartość zwracana metody
    2. Parametry metody

1. Metody w języku Java

W języku Java metody są odpowiednikami  funkcji w językach C++ i Python. Metody są również podprogramami, ale przynależą do klas i są definiowane wewnątrz nich. Przykładem metody jest statyczna metoda main(), od której zaczyna się wykonywanie programu w języku Java.

Aby wywołać metodę statyczną zdefiniowaną w tej samej klasie, wystarczy, że użyjemy jej nazwy. Pokazano to w przykładzie 1., gdzie ze statycznej metody main() wywołujemy trzy razy inną metodę statyczną przywitajSie(). Metody statyczne mogą się odwoływać bezpośrednio wyłącznie do statycznych pól i innych statycznych metod klasy, w której są zadeklarowane.

Przykład 1. Metoda statyczna i jej użycie

//plik Program.java
package pl.migra.ir.java;

public class Program {
   public static void main(String[] args) { // deklaracja metody main
       // trzy wywołania metody przywitajSie
       przywitajSie();
       przywitajSie();
       przywitajSie();
   }

   private static void przywitajSie() { // deklaracja metody przywitajSie
       System.out.println("Dzień dobry!");
   }
}

Ćwiczenie 1. Użycie metod statycznych

  1. Otwórz projekt Metody, w którym są zapisane wszystkie programy potrzebne do rozwiązania ćwiczeń w temacie C7.
  2. Otwórz plik Program. Skompiluj i uruchom program.
  3. Dodaj do klasy z przykładu 1. metodę pozegnajSie(), która wyświetli na ekranie odpowiedni tekst i wywołaj ją.
  4. Skompiluj i uruchom program. Zapisz plik pod tą samą nazwą.

Metody, które nie są statyczne, możemy wywołać jedynie poprzez odwołanie do obiektu, do którego przynależą – jak w przykładzie 2. Takie metody mogą się odwoływać bezpośrednio do wszystkich pól i metod klasy, w której są zadeklarowane.

Przykład 2. Metoda obiektu i jej użycie

// plik Kotek.java
package pl.migra.ir.java;

public class Kotek {
   // prywatne pole zliczające
   private int poglaskano = 0;

   // deklaracja metody poglaszcz
   public void poglaszcz() {
       poglaskano++;
       System.out.println("Miau!");
   }
}

// plik Metoda.java
// nie potrzebujemy instrukcji import aby użyć klasy Kotek,
// ponieważ umieścimy ją w tym samym projekcie

public class Metoda {
   public static void main(String[] args) {
       // stworzenie obiektu klasy Kotek
       // i przypisanie referencji do niego do zmiennej k
       Kotek k = new Kotek();
       // wywołanie metody poglaszcz()
       k.poglaszcz();
   }
}

Ćwiczenie 2. Używamy metod obiektu

  1. Otwórz plik Metoda.java (z projektu Metody).
  2. Skompiluj i uruchom program. Zauważ, że przy wywołaniu metody poglaszcz() kotek „miauczy”. Zmień metodę w taki sposób, aby przy trzecim pogłaskaniu i kolejnych dodatkowo „mruczał”. Przetestuj działanie tej metody.
  3. Zapisz plik Metoda pod tą samą nazwą.

2. Dostęp do metod, pól i klas

Metody klas w języku Java, podobnie jak ich pola, mogą mieć określone w ich deklaracji modyfikatory dostępu. Opisano je w poniższej tabeli.

Dostęp z:tej samej klasyinnej klasy w tym samym pakiecieklasy potomnej w innym pakiecieniezwiązanej klasy w innym pakiecie
publictaktaktaktak
protectedtaktaktaknie
(brak modyfikatora)taktaknienie
privatetaknienienie
Tabela 1. Modyfikatory dostępu w języku Java

 

Jedną z zasad programowania  obiektowego jest ograniczenie do minimum dostępu do elementów programu, czyli hermetyzacja.

Ćwiczenie 3. 

  1. Do metody poglaszcz() z przykładu 2. użyliśmy modyfikatora public. Jaki najbardziej restrykcyjny modyfikator dostępu możemy zastosować do metody poglaszcz() zamiast public?
  2. Czy metoda przywitajSie() z przykładu 1. ma odpowiedni modyfikator dostępu?

Również same klasy mogą mieć modyfikator dostępu. Zauważ, że wszystkie stworzone przez nas do tej pory klasy mają modyfikator public i są dostępne z dowolnej innej klasy niezależnie od jej pakietu. W przypadku klas najwyższego poziomu (czyli takich, które są zadeklarowane na początku pliku z rozszerzeniem java, a ich nazwa odpowiada jego nazwie) możemy użyć wyłącznie modyfikatora public albo go zupełnie pominąć. Jeśli pominiemy modyfikator, do klasy będziemy mogli odwołać się wyłącznie z innej klasy w tym samym pakiecie.

Ćwiczenie 4. Stosujemy hermetyzację

  1. W pliku Kotek.java spróbuj zmienić modyfikatory dostępu dla klasy Kotek i metody poglaszcz().
  2. Spróbuj również przenieść klasę do innego pakietu.
  3. Po zmianach sprawdź, czy IDE zasygnalizuje błędy w klasie Metoda przy odwołaniu do obiektu klasy Kotek.

3. Deklaracja metody

W przykładach 1. i 2. pokazano kilka deklaracji metod. Pierwszą częścią takiej deklaracji (do nawiasów klamrowych) nazywamy nagłówkiem albo sygnaturą metody. W nawiasach klamrowych jest umieszczana treść metody nazywana również jej ciałem albo implementacją.

public static void main(String[] args) { … }
private static void przywitajSie() { … }
public void poglaszcz() { … }
Zgodnie z zasadami programowania obiektowego można zadeklarować metody o tej samej nazwie, które różnią się zestawem parametrów. Mówimy wtedy o metodach przeciążonych.

W języku Java kolejność deklaracji metod wewnątrz klasy jest dowolna, chociaż przyjmuje się, że najpierw deklarujemy metody publiczne.

Ćwiczenie 5. Deklarujemy metodę niezwracającą wartości

  1. Zaproponuj sygnaturę metody, która wypisze wszystkie dzielniki podanej liczby.
  2. Zadeklaruj metodę o sygnaturze utworzonej w punkcie 1.
  3. Napisz program wykorzystujący metodę zadeklarowaną w punkcie 2.
  4. Zapisz program w pliku pod nazwą Dzielniki.

3.1. Wartość zwracana metody

W każdej z przykładowych deklaracji przed nazwą metody występują dodatkowe informacje:

  • opcjonalny modyfikator dostępu,
  • opcjonalne oznaczenie statyczności,
  • typ wartości zwracanej przez metodę.

Dotychczas używaliśmy słowa kluczowego void na oznaczenie metod, które nie zwracają żadnych wartości. Takie metody najczęściej wyprowadzają dane na ekran albo zmieniają wartości pól klasy. Metody niezwracające wartości mogą użyć instrukcji return, aby od razu zakończyć działanie, jak pokazano w przykładzie 3.

Przykład 3. Użycie return w metodzie niezwracającej wartości

static void powtorz(String napis, int ileRazy) {
   // gdy ileRazy jest liczbą ujemną wypisujemy komunikat
   // i kończymy działanie metody
   if (ileRazy < 0) {
       System.out.println("Podano liczbę ujemną: " + ileRazy);
       return;
   }

   for (int i = 0; i < ileRazy; i++) {
       System.out.println(napis);
   }
}

Uwaga: Metoda powtórz zostanie użyta w programie Napisy.java (ćwiczenie 7.).

W języku Java można definiować metody, które zwracają wartość. Może to być wartość liczbowa, jak w poniższych przykładach.

public static int suma(int a, int b) { … }
public static double iloczyn(double a, double b) { … }
public int liczbaZwierzat() { … }

Metody zwracające wartość muszą zakończyć swoje działanie instrukcją return, która zwróci jako wynik wartość podanego wyrażenia np. tak, jak w poniższej metodzie:

public static int suma(int a, int b) {
   return a + b;
}

Ćwiczenie 6. Deklarujemy metody zwracające wartość z parametrami

  1. Zaproponuj sygnaturę metody sprawdzającej, czy dana liczba całkowita jest liczbą pierwszą.
  2. Zadeklaruj metodę o sygnaturze utworzonej w punkcie 1.
  3. Napisz program wykorzystujący metodę zadeklarowaną w punkcie 2.
  4. Zapisz program w pliku pod nazwą Pierwsza.

3.2. Parametry metody

Oprócz typu wartości zwracanej przez metodę w deklaracji jest również zawarta informacja o parametrach metody. Lista parametrów jest umieszczona w nawiasach za nazwą metody, a każdy parametr musi mieć określony typ. Lista może być pusta – wtedy pusty jest nawias, jak w przypadku metod przywitajSie() i poglaszcz(). Poniżej podano przykłady deklaracji metod z parametrami:

public static int max(int a, int b) { … }
private void zapisz(String napis) { … }
String polacz(String[] napisy) { … }

W języku Java można zadeklarować metodę ze zmienną liczbą parametrów. W nagłówku metody do typu ostatniego parametru na liście dodajemy wtedy trzy kropki, jak pokazano w przykładzie 4.

Przykład 4. Deklarowanie metody ze zmienną liczbą parametrów

//plik Napisy.java
package pl.migra.ir.java;

public class Napisy {
   private static String polacz(String separator, int... liczby) {
       String rezultat = "";
       for (int i = 0; i < liczby.length; i++) {
           rezultat += liczby[i];
           if (i + 1 < liczby.length) {
               rezultat += separator;
           }
       }
       return rezultat;
   }

   private static String polacz(String przed, String po, String separator, int... liczby) {
       return przed + polacz(separator, liczby) + po;
   }

   public static void main(String[] args) {
       // wywołujemy tę samą metodę z różną liczbą argumentów
       System.out.println(polacz(", ", 1, 2, 3));
       System.out.println(polacz("|", 100, 101, 102, 103));
       // możemy również podać bezpośrednio tablicę liczb
       int[] liczby = {1, 2, 3, 4};
       System.out.println(polacz("(", ")", ", ", liczby));
       // parametr "liczby" jest w poniższym przypadku pustą tablicą
       System.out.println(polacz(":"));
   }
}

Ćwiczenie 7. Deklarujemy metodę ze zmienną liczbą parametrów

  1. Otwórz plik Napisy.java (z projektu Metody). Skompiluj i uruchom program.
  2. Wyjaśnij, co się dzieje w poszczególnych częściach programu. Zapisz treść zadania, które realizuje ten program,  w tym podaj zadania cząstkowe, realizowane przez poszczególne metody.

Przykład 5. Implementacja algorytmu Euklidesa w wersji z odejmowaniem w języku Java

//plik Euklides.java
package pl.migra.ir.java;

public class Euklides {
   private static int nwd(int a, int b) {
       while (a != b) {
           if (a > b) {
               a = a - b;
           } else {
               b = b - a;
           }
       }
       return a;
   }

   public static void main(String[] args) {
       System.out.println(nwd(10, 3));
       System.out.println(nwd(10, 2));
       System.out.println(nwd(10, 7));
       System.out.println(nwd(10, 5));
       System.out.println(nwd(10, 8));
   }
}

Ćwiczenie 8. Realizujemy algorytm Euklidesa w języku Java

  1. Przypomnij sobie algorytm Euklidesa do odnajdywania największego wspólnego dzielnika dwóch liczb. Omawialiśmy go w ćwiczeniach w językach C++ i Python (temat C9, część II Materiału edukacyjnego). W przykładzie 5. pokazano jego implementację w języku Java w wersji z odejmowaniem.
  2. Otwórz plik Euklides.java (z projektu Metody). Uruchom program i sprawdź jego działanie.
  3. Zmień program na wersję algorytmu Euklidesa z resztą z dzielenia (z operatorem %).
  4. Dodaj do programu metodę zwracającą najmniejszą wspólną wielokrotność (NWW), wykorzystując metodę nwd().
  5. Zapisz plik pod tą samą nazwą.

Zadania

  1. Zaproponuj sygnatury podanych metod:
    1. nowa metoda w klasie Kotek (z przykładu 2.) zwracająca imię zwierzęcia,
    2. metoda sprawdzająca, czy liczba a dzieli liczbę b bez reszty,
    3. metoda sumująca podane liczby całkowite (ze zmienną liczbą argumentów).
      Zadeklaruj metody o sygnaturach utworzonych w punktach a-c. Wyjaśnij, które z tych metod powinny być statyczne. Napisz programy wykorzystujące te metody.
  2. Utwórz statyczną metodę, która sprawdzi, czy podana liczba jest podzielna przez drugą podaną liczbę. Wykorzystaj przeciążenie metody, tworząc kolejną metodę sprawdzającą, czy dana liczba jest podzielna przez 7.
    Zdefiniuj metodę suma_kwadratow() zwracającą sumę kwadratów podanych liczb rzeczywistych. Omów, czy będzie to metoda statyczna. Wykorzystaj metodę suma_kwadratow() do zdefiniowania metody sprawdzającej, czy z podanych trzech liczb można zbudować trójkąt. Napisz program wykorzystujący te metody.

  3. Dla zainteresowanych
  4. Z ciągu n liczb naturalnych wypisz liczby, których suma cyfr jest większa od 30. W programie wykorzystaj metodę sumaCyfr(liczba), która obliczy sumę cyfr liczby podanej jako parametr. W celu obliczenia wartości cyfry skorzystaj z możliwości obliczenia reszty z dzielenia przez 10.
  5. Po umieszczeniu przykładu 4. w IDE pojawia się sugestia zastąpienia instrukcji rezultat += liczby[i]; przez coś innego. Zatwierdź sugestię IDE. Omów, co się zmieniło. Odnajdź dokumentację klasy, której automatycznie użyło IDE.