Třídy a objekty

Základní syntaxe třídy

  • Třída je umístěna v souboru Person.java.

  • Přeložený byte code je v souboru Person.class.

  • Konvence pro pojmenování tříd: CamelCase.

  • Viditelnost: Skoro vždy public, protože chceme, aby objekty spolupracovaly (byly dostupné jiným objektům).

public class Person {
   private String name;
   public String getName() {
     return name;
   }
   public String setName(String name) {
     return this.name = name;
   }
   public void printInfo() {
     System.out.println("I am " + getName().toUpperCase());
   }
}

Metody

  • Veřejné metody definují chování objektu (jaké služby nabízí jiným objektům).

  • Konvence pro pojmenování tříd: camelCase.

  • Dostupnost (scope): Celá třída, tj. kód libovolné metodu může volat jinou metodu dané třídy. Dostupnost metody mimo třídu je závislá na modifikátoru viditelnosti.

  • Viditelnost: public pro veřejné metody, private nebo protected pro lokální metody (slouží většinou k dekompozici veřejných metod).

public class Person {
   private String name;
   public String getName() {
     return name;
   }
   public String setName(String name) {
     return this.name = name;
   }
   public void printInfo() {
     System.out.println("I am " + getName().toUpperCase());
   }
}

Atributy

  • Hodnoty definují stav objektu, který se může měnit a ovlivňovat chování.

  • Konvence pro pojmenování tříd: camelCase.

  • Dostupnost (scope): Celá třída. Viditelnost mimo třídu je závislá na modifikátoru viditelnosti.

  • Kolize jmen atributu s lokální proměnnou: Přednost má lokální proměnná. Pro odkaz na atribut lze v případě kolize použít prefix this..

  • Viditelnost: Skoro vždy private z důvodu zapouzdření. Pro přístup se využívají metody get a set (tzv. gettery a settery).

public class Person {
   private String name;

   public String getName() {
     return name;
   }

   public String setName(String name) {
     return this.name = name;
   }

   public void printInfo() {
     System.out.println("I am " + getName().toUpperCase());
   }
}

Vytváření objektů

  • Tzv. instanciace třídy.

  • Voláním konstruktoru pomocí new. Konstruktor má stejný název, jako je název třídy.

   Person jan = new Person();
   jan.setName("Jan Novak");
   Person karel = new Person();
   karel.setName("Karel Novak");
}

Rušení objektů

  • Java neumožňuje programátorsky vyvolat nebo jinak ovlivňovat vyklízení objektů z paměti.

  • Stará se o to přímo JVM. Sleduje, jestli daný objekt někdo referencuje a nedostupné objektu automaticky maže.

   Person jan = new Person();
   jan.setName("Jan Novak");
   jan = new Person(); // Jan Novak disappears from the memory automatically
   jan.setName("Jan Novotny");
}

Objektové proměnné

  • Objektová proměnná ukládá adresu objektu.

  • Deklarací objektové proměnné se jí nepřiřadí adresa objektu v paměti! Její hodnota je null. Teprve přiřazením pomocí = nebo předáním parametru se přiřadí adresa konkrétního objektu.

   Person jan;
   if (jan == null) { // always true
      jan = new Person();
   }
   jan.setName("Jan Novak");
}

Spolupráce objektů

  • Objekt Person spolupracuje s objektem String

public class Person {
   private String name;
   public String getName() {
     return name;
   }
   public String setName(String name) {
     return this.name = name;
   }
   public void printInfo() {
     System.out.println("I am " + getName().toUpperCase());
   }
}

Spolupráce objektů (pokr.)

  • Spolupráce více objektů jedné třídy.

public class Account {
   private double balance; // 0.0
   public void add(double amount) {
      balance += amount;
   }
   public void writeBalance() {
      System.out.println(balance);
   }
   public void transferTo(Account whereTo, double amount) {
      balance -= amount;
      whereTo.add(amount); // whereTo is another account
   }
}
   Account petrsAccount = new Account();
   Account ivansAccount = new Account();
   petrsAccount.add(100.0);
   ivansAccount.add(20.0);
   petrsAccount.transferTo(ivansAccount, 30.0);
   petrsAccount.writeBalance(); // prints 70.0
   ivansAccount.writeBalance(); // prints 50.0

Třída String

  • Třída jako každá jiná. Nabízí metody, jde instanciovat pomocí new apod.

  • Java ale pro práci s řetězci nabízí zjednodušenou syntaxi.

  • String str = "ahoj"; namísto String str = new String("ahoj");

  • `"ahoj" + " všichni" namísto volání operací pro zřetězení.

Třída spustitelná z příkazové řádky

  • Princip běhu objektového programu spočívá v tom, že v paměti vznikají (a zanikají) objekty, vzájemně si předávají odkazy na sebe a vzájemně se volají.

  • Někde to musí začít, tj. nejprve se musí v paměti vytvořit iniciální objekt, který spustí danou kaskádu vytváření a volání dalších objektů.

  • Jako iniciální může soužit objekt libovolné třídy, která implementuje metodu main. Dokud je objekt činný v paměti, program běží. Pokud objekt skončí, končí celý program (a všechny vytvořené objekty se uvolní z paměti).

  • Metoda main musí být veřejná (public), statická (static) a nevrací žádnou hodnotu (void).

  • Metoda musí mít parametry typu String (řetězec), které se předávají při spuštění z příkazového řádku do pole String[] args.

public class Demo {
   public static void main(String[] args) {
      Account petrsAccount = new Account();
      // ... etc.
   }
}

Program "Hello World!"

  • Trivilální program pro výpis "Hello World!" vypadá následovně.

  • Využívá spolupráci s třídou System. Nejedná se ale o klasickou spolupráci na úrovni objektů jak jsme viděli výše. Vysvětlíme si příště.

  • Příklad zároveň demonstruje, jak snadno v Javě něco vypsat na standardní výstup.

public class Demo {
   public static void main(String[] args) {
      System.out.println("Hello World!");
   }
}
  • Pozor na rozdíl mezi vypsáním řetězce a jeho vrácením:

public void writeString() {
  System.out.println("Sample text"); // writes it
}
public String returnString() {
  return "Sample text"; // does not write it
}