Objekty a třídy


Materiály

Třídy

O třídách bychom mohli řící, že jsou šablonou, která definuje vlastnosti a chování určité skupiny objektů. V Javě každá třída musí být umístěna v samostatném souboru a tento soubor musí mít stejný název jako třída v něm obsažená. Vysvětleno na příkladu; třída Bar musí být v souboru Bar.java. Každá třída musí být obsažena v baličku, který určuje cestu ke třídě a také slouží jako jmenný prostor. Příklad java.lang.String a cz.upol.zp3jv.String.


    //Jméno třídy začíná velkým písmenem a stejně tak každé další slovo.
    //V názvech není dovoleno používat _ nebo -
    class Bar {
        //Definice atributů

        //Konstruktory

        //Metody
    }

Atributy

Atributy definují vnitřní stav objektu.

    <viditelnost> <modifikátory> <typ> <název> [= inicializační hodnota] ;

Viditelnost

Ve většině případů jsou atributy deklarovány jako private a pro přístup se využívají gettery a settery (viz níže).

Modifikátory

Typ

Určuje datový typ atributu: int, String, ...

Název

Název atributu začíná malým pismenem a každé další slovo začíná velkým písmenem. Pokud je atribut konstanta všechny znaky jsou psány velým písmem a slova se oddělují _.

Konstruktory

Konstruktory slouží pro vytvoření objektu dané třídy. Jejich syntaxe je podobná metodám jejich název je ale totožný s názvem třídy a nemají návratový typ.

    <viditelnost> <název třídy> (typ1 argument1,  typ2 argument2, ..., typN argumentN) {
        super(argument1, ...); // Zavolání rodičovského kontruktoru

        // Inicializace proměných
    }

Metody

Metody definují chování objektu. Důležité metody jsou gettery a settery pro jednotlivé atributy. Zajistí se tím princip zapouzdření.

    <viditelnost> <modifikátory> <návratový typ> <název> (typ1 argument1,  typ2 argument2, ..., typN argumentN) {
        // Tělo metody
    }

Viditelnost

Viditelnost je stejná jako u atributů.

Modifikátory

Návratový typ

Jako návratový typ lze zvolit primitivní datový typ nebo objekt. Pokud nechceme aby metoda vracela hodnotu zle použít jako návratový typ void.

Název

Název metody začíná malým písmenem a každé další slovo začíná velým písmenem.

Metody s proměnným počtem parametrů

    
        public static int sum(int a, int... b) {

        }

        // Výše uvedená funkce je kompilátorem převedena na

        public static int sum(int a, int[] b) {

        }
    

Objekty

Objekt je instancí třídy. Mějme třídu Student, která představuje šablonu pro studenta.

        
    public class Student {
        // Atributy
        private String name;
        private int age;
        private int clazz;

        // Konstruktory
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
            clazz = 1;
        }

        // Metody

        void celebrateBirthday() {
            age += 1;
        }

        void passAllExams() {
            clazz += 1;
        }

        //Gettery a Settery

        public String getName() {
            return name;
        }

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

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public int getClazz() {
            return clazz;
        }

        public void setClazz(int clazz) {
            this.clazz = clazz;
        }
    }
        
    

Instancí výše uvedené třídy je například každý student katedry informatiky. Tyto instance nebo-li objekty je liší hodnotami atributů name, age a clazz. Ovšem chování, které definují metody je stejné.

Práce s objekty

    
       // Vytvoření nového objektu
        Student novak = new Student("Jan Novak", 20);

        // Volání metod
        novak.celebrateBirthday(); // age = 21
        novak.getAge() // -> 21

        novak.age // Chyba age je deklarovaná jako private.

    

Dědičnost

Pomocí dědičnosti můžeme omezit redundanci kódu. V Javě lze dědit pouze z jedné třídy. Dědičnost přidáme do definice třídy pomocí extends. Pro ilustraci jak funguje dědičnost použijeme třídu Student a definujeme ji jako potomka třídy Person. Ve třídě Person lze vidět že má shodné atributy name a age. Děděním z třídy Person můžeme vytvořit další třídy jako je například Teacher.

    
        public class Person {
            private String name;
            private int age;

            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }

            void celebrateBirthday() {
                age += 1;
            }

             public String getName() {
                return name;
            }

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

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }
        }

        // Definice třídy Student jako potomka třídy Person
        public class Student extends Person {
            private int clazz;

            public Student(String name, int age) {
                super(name, age)
                clazz = 1;
            }

            void passAllExams() {
                clazz += 1;
            }

            public int getClazz() {
                return clazz;
            }

            public void setClazz(int clazz) {
                this.clazz = clazz;
            }
        }

    

Rozhraní

Pomocí rozhraní se v Javě řeší vícenásobná dědičnost. Rozhraní se definují stejně jako třídy pouze místo klíčového slova class je použito interface. Každá třída může implementovat libovolné množství rozhranní. V Javě 8 lze v rozhraní implementovat metody které jsou označeny jako static. Pokud metodu označíme jako default tak její implementace může ale nemusí být překryta v implementující třídě.

    
        public interface Introduce {
            public void introduceMyself();
        }


        public class Student extends Person implements Introduce {
            private int clazz;

            public Student(String name, int age) {
                super(name, age)
                clazz = 1;
            }

            void passAllExams() {
                clazz += 1;
            }

            public int getClazz() {
                return clazz;
            }

            public void setClazz(int clazz) {
                this.clazz = clazz;
            }

            public void introduceMyself() {
                System.out.print("Hello I am student and my name is " + getName());
            }
        }


        // Příklad použití
        Introduce selfIntroduceStudent = new Student("Tomas Marny", 20);
        selfIntroduceStudent.introduceMyself() // -> Hello I am student and my name is Tomas Marny


        // Ověření typu objektu
        if (selfIntroduceStudent instanceof Student) {
            System.out.print("Student");
        }

    

Úkoly

  1. Implementujte třídu Point představující bod v rovině určený dvěma souřadnicemi. V tříde Point implementujte metodu double distance(Point p) vracející vzdálenost od daného bodu.

  2. Implentujte třídu Line představující úsečku. Implementujte metody: double getLength() a double distance(Point p). Vzdálenost bodu od úsečky berte v tomto případě jako nejmenší vzdálenost mezi bodem a všemi body ležícími na úsečce.

  3. Implementujte třídu Rectangle představující obdelník, který má strany vodorovné s osami X a Y. Třída by měla mít dva konstruktory, jeden vytvářející obdelník pomocí dvou bodů, další vytvářející obdelník na základě bodu, výšky a šířky. Implementujte metodu double getArea() vracející obsah daného obrazce. Implementujte metodu double distance(Point p) vracející vzdálenost od daného bodu. Vzdálenost bodu od obdelníku berte v tomto případě jako nejmenší vzdálenost mezi bodem a všemi body ležícími na stranách obdelníku.

  4. Implementujte třídu Square představující čtverec. Třída by měla mít konstruktor vytvářející objekt na zákládě souřadnice a délky strany. Implementujte metodu double getArea(). Implementujte metodu double distance(Point p) vracející vzdálenost od daného bodu.

  5. Implementujte třídu Circle představující kružnici. Třída by měla mít konstruktor vytvářející objekt na zákládě souřadnice a poloměru. Implementujte metodu double getArea(). Implementujte metodu double distance(Point p) vracející vzdálenost od daného bodu. Vzdálenost bodu od kružnice berte v tomto případě jako nejmenší vzdálenost mezi bodem a všemi body ležícími na kružnici. Vzdálenost nemůže mít zápornou hodnotu!

  6. Třídy z předchozích příkladů upravte tak, aby se díky dědičnosti omezila redundance kódu. Pokud to má opodstatnění, použijte rozhraní.

Úkoly posílejte na email r.vyjidacek@gmail.com s předmětem ZP3JV02. Termín odevzdání do půlnoci 11. 10. 2017. Odevzdávejte pouze zdrojové kódy v archivu zip.