OCPJP Inner classes.

Slides:



Advertisements
Podobne prezentacje
Wstęp do strumieni danych
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
Mgr inż.Marcin Borkowski Podstawy Java Krótkie wprowadzenie dla studentów Wyższej Szkoły Ekologii i Zarządzania
Programowanie obiektowe Andrzej Ziółkowski Wykład 3.
Klasy i obiekty.
Tworzenie i obsługa programów – przykład 3 uwagi cd. Wykorzystując różne klasy biblioteki języka Java należy pamiętać w jakim pakiecie się znajdują. Wszystkie.
Sposoby implementacji asocjacji
Dziedziczenie wieloaspektowe
Implementacja ekstensji klasy
Programowanie Obiektowe w Javie (c.d.)
Nguyen Hung Son Uniwersytet Warszawski
Programowanie obiektowe w Javie
Podstawy języka Java Nguyen Hung Son Uniwersytet Warszawski.
Model – View - Controler
W ZORCE P ROJEKTOWE … czyli ktoś już rozwiązał Twoje problemy!
Programowanie sieciowe w Javie
Czytanie, pisanie i rysowanie – cd.. Jeszcze jeden strumyk PrintStream działa jak PrintWriter, ale: Używa domyślnego (systemowego) kodowania Nie wyrzuca.
Czytanie, pisanie i rysowanie (czyli klasa I szkoły podstawowej)
142 JAVA – sterowanie i wątki public class A20 extends javax.swing.JApplet implements ActionListener { private int licznik = 0; private JTextField t =
Język Java Wielowątkowość.
Hibernate relacje.
przygotował Michał Wdaniec
Klasy w C++. Deklaracja klasy class NazwaTwojejKlasy { //w tym miejscu piszemy definicje typów, //zmienne i funkcje jakie mają należeć do klasy. }; //tutaj.
Pakiety w Javie Łukasz Smyczyński (132834). Czym są pakiety? Klasy w Javie są grupowane w pewne zbiory zwane pakietami. Pakiety są więc pewnym podzbiorem.
Java 3 MPDI Programowanie obiektowe W7. import java.io.*; public class X { // kontrukcja throws – określenie jakie wyjątki może dana metoda // sygnalizować
Podstawy inżynierii oprogramowania Zofia Kruczkiewicz
PIO 3_2, Zofia Kruczkiewicz1 Wykład 3 – część druga Iteracyjno-rozwojowy cykl oprogramowania 3.
JAVA – wstęp.
W większości języków programowania biblioteki wejścia/wyjścia ukrywają szczegóły obsługi poszczególnych mediów pod abstrakcją strumienia (ang. stream).
Tworzenie aplikacji mobilnych
Programowanie obiektowe III rok EiT
Tworzenie aplikacji mobilnych
Programowanie obiektowe – zastosowanie języka Java SE
JAVA.
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Seminarium problemowe
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
PIO 2_2, Zofia Kruczkiewicz1 Wykład 2 – część druga Iteracyjno-rozwojowy cykl oprogramowania 2.
C# Platforma .NET CZ.3 Kuba Ostrowski.
Java 3 MPDI Programowanie obiektowe W5. Java - obiektowy język programowania stworzony przez firmę Sun Microsystems. Java jest językiem tworzenia programów.
1 Strumienie Hierarchie klas strumieniowych, strumienie bajtowe - klasy InputStream i OutputStream i ich metody, klasa File, strumienie plikowe, strumienie.
  ELEMENTY JĘZYKA JAVA komentarze w Javie, słowa kluczowe i operatory, proste typy danych, tablice, podstawowy zestaw instrukcji.
Kurs języka C++ – wykład 3 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Obiektowe metody projektowania systemów Abstract Factory design pattern (aka. Kit)
Paweł Starzyk Obiektowe metody projektowania systemów
PIO 3_2, Zofia Kruczkiewicz1 Wykład 3 – część druga Iteracyjno-rozwojowy cykl oprogramowania 3.
Object-relational mapping (aka O/RM, ORM, and O/R mapping)
Kolekcje (3) Zbiory. Porównywanie i porządkowanie elementów kolekcji. (c) Krzysztof Barteczko 2014.
do programowania obiektowego w języku Groovy
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
InMoST, Java – przykładowa aplikacja Bartosz.Michalik
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Programowanie Obiektowe – Wykład 6
Wątki, programowanie współbieżne
(według:
(c) Krzysztof Barteczko 2014
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Klasy wewnętrzne. Praktyka użycia interfejsów i klas wewnętrznych
Iteracyjno-rozwojowy cykl oprogramowania 3
Programowanie obiektowe – zastosowanie języka Java SE
PGO Interfejsy Michail Mokkas.
Zdarzenia (eventy) Zdarzenia służą do powiadomienia użytkownika, gdy w używanej klasie dojdzie do pewnych wydarzeń zdefiniowanych przez twórcę klasy.
PGO - Projektowanie i implementacja pierwszych klas
Tworzenie wątków w Javie
Zapis prezentacji:

OCPJP Inner classes

Wprowadzone w Java ?.? inner classes method-local inner classes anonymous inner classes static nested classes Q1, Java 1.1

Inner classes class BabaJaga { class WszystkieDzieciZjada { } javac BabaJaga.java Jakie pliki utworzą się na dysku? Q2, Klasa wewnętrzna to klasa zadeklarowana między klamrami deklaracji innej klasy

BabaJaga.class BabaJaga$WszystkieDzieciZjada.class

class ZlowrogiDelfin { class MalyZlowrogiDelfin { static void main(String[] args) { System.out.println( „NIE dla delfinariów!”); } Q3, Nie można nawet takiego programu skompilować. Klasa wewnętrzna nie może posiadać statycznych metod ani pól. W następnym slajdzie wytłumaczyć dlaczego nie może mieć i jaki to ma związek z bindingiem. Czy tak skompilowany program można uruchomić poleceniem: java ZlowrogiDelfin$MalyZlowrogiDelfin?

public class Pakero { private int obwodKabla = 50; public String odzywka = „Koks”; class DanePakera { public void ileMaWKablu() { out.println(„Obwod kabla: ” + obwodKabla); } public void jakaMaOdzywke() { out.println(„Odżywka: ” + odzywka); public void calaPrawdaOPakerze() { DanePakera dp = new DanePakera(); dp.ileMaWKablu(); dp.jakaMaOdzywke(); Instancje klasy wewnętrznej można utworzyć tylko poprzez instancję klasy zewnętrznej. Wynika to z tego, że klasy wewnętrzne są powiązane z danymi klasy zewnętrznej i potrzebują wskaźnika na klasę otaczającą. W podanym przykładzie klasa wewnętrzna ma dostęp do prywatnego i publicznego pola klasy zewnętrznej. Nie jest to łamanie enkapsulacji ponieważ klasa wewnętrzna jest również traktowana jak pole klasy zewnętrznej i tak jak zwykłe metody klasy zewnętrznej ma dostęp do jej pól i metod. Najczęściej instancję klasy wewnętrznej tworzy sama klasa zewnętrzna (bezpośrednio lub przy użyciu jakiejś metody typu helper np. makeDanePakera())

public void static main(String[] args) { new Pakero().new DanePakera().ileMaWKablu(); Pakero.DanePakera dp = new Pakero() .new DanePakera() .jakaMaOdzywke(); } Tworzenie instancji klasy wewnętrznej poza klasą zewnętrzną.

class Smerfetka { class SekretSmerfetki { void sekretPierwszy { out class Smerfetka { class SekretSmerfetki { void sekretPierwszy { out.println(„Osiłek is soo cool..”); } static void zdradzSekret() { SekretSmerfetki ss = new SekretSmerfetki(); ss.sekretPierwszy(); public void main(String[] args) { Smerfetka.zdradzSekret(); Q4, Czy można utworzyć klasę wewnętrzną z metody statycznej? Nie można. W statycznym kontekście wskaźnik this jest niedostępny.

class Tieto { int zysk = 1_000_000; int kierownicy = 20; int pracownicy = 700; boolean kryzys = true; boolean zarzadZadowolonyZZysku = false; boolean kierownikZadowolonyZPracownika = false; boolean koniunkcjaMarsJowisz = false; int procentZysku(int p) { return p * zysk / 100; } class Zarzad { int zysk = 950_000; int pensja() { return procentZysku(80); } class Kierownicy { int pensja() { return procentZysku(15); } class Pracownicy { int pensja() { return zysk - Zarzad.this.pensja() - Kierownicy.this.pensja(); } int pensja1() { return Zarzad.Kierownicy.Pracownicy.this.pensja(); } int pensja2() { return Kierownicy.Pracownicy.this.pensja(); } int mojaPensja() { return pensja() / pracownicy; } int mojaPremia() { if(!kryzys && zarzadZadowolonyZZysku && kierownikZadowolonyZPracownika && koniunkcjaMarsJowisz) return 100 / pracownicy; else return 0; } Q5, Każda klasa wewnętrzna jest powiązana z klasą otaczającą i każdą kolejną klasą otaczającą. Pracownicy.pensja () – z której klasy jest pobierana wartość zysk i jak zrobić, żeby była pobierana z klasy Tieto? (Tieto.this.zysk)

int access$0 { return x; } int access$1 { return y; } class A { private int m; public void g() { A$B ob = new A$B(); ob.f(); m = ob.access$0() * ob.access$1(); } int access$0 { return m; class A { private int m; private class B { private int x; private int y; void f() { x = m; } } public void g() { B ob = new B(); ob.f(); m = ob.x * ob.y; class A$B { A this$0; private int x; void f() { x = this$0.access$0(); } int access$0 { return x; } int access$1 { return y; } access$0, A$B – package level visibilty JVM nie rozumie klas wewnętrznych Java 1.1 implementation w Java 1.2 ograniczono dostęp do zmiennych prywatnych tylko do właściwych klas (wymiana sekretnego klucza). Do tej porty metody access były dostępne w obrębie całego pakietu Inicializacja this$0 odbywa się w konstruktorze (parametr jest niejawnie doklejany)

Modyfikatory final abstract public private protected static * strictfp * - w tym przypadku static zmienia klasę wewnętrzną w klasę zagnieżdżoną

Method-Local Inner Classes class NaszaKlasa { int uzytkownikow; void statystyka { class Statystyka { int kobiet; int mezczyzn; } Statystyka s = new Statystyka(); println(„kobiet: ” + s.kobiet + „/” + uzytkownikow); println(„mezczyzn: ” + s.mezczyzn + „/” + uzytkownikow); Klasy definiowane w metodach mogą być tylko instancjonowane tylko w tych metodach. Taka klasa ma dostęp do wszystkich pól klasy zewnętrznej ale nie ma dostępu do zmiennych lokalnych danej metody (dlaczego – następny slajd).

class Warzywniak { String godzinyOtwarcia() { final String nazwa = "Warzywko u Stasia"; class GodzinyOtwarcia { String utworzListe() { class Godzina { Godzina(String d, int go, int gd) { dzien = d; godzOd = go; godzDo = gd; } String dzien; int godzOd; int godzDo; public String toString() { return dzien + „:” + godzOd + " - " + godzDo + "\n"; return "Godziny otwarcia sklepu: " + nazwa + "\n" + new Godzina("Poniedzialek", 10, 18) + new Godzina("Sroda", 9, 17) + new Godzina("Sobota", 10, 15); GodzinyOtwarcia godziny = new GodzinyOtwarcia(); return godziny.utworzListe(); System.out.println(new Warzywniak().godzinyOtwarcia()); Q6, Dlaczego zmienna nazwa musi być final?

class Warzywniak { String godzinyOtwarcia() { final String nazwa = "Warzywko u Stasia"; class GodzinyOtwarcia { + private String nazwa; + GodzinyOtwarcia(String nazwa) { this.nazwa = nazwa; } String utworzListe() { class Godzina { Godzina(String d, int go, int gd) { dzien = d; godzOd = go; godzDo = gd; } String dzien; int godzOd; int godzDo; public String toString() { return dzien + „:” + godzOd + " - " + godzDo + "\n"; return "Godziny otwarcia sklepu: " + nazwa + "\n" + new Godzina("Poniedzialek", 10, 18) + new Godzina("Sroda", 9, 17) + new Godzina("Sobota", 10, 15); + GodzinyOtwarcia godziny = new GodzinyOtwarcia(nazwa); return godziny.utworzListe(); Zmienna nazwa musi być final ponieważ jest to zmienna lokalna i jest tworzona na stosie. Ramka stosu znika natychmiast po zakończeniu wykonywania się metody a instancja klasy lokalnej może żyć dłużej i po zakończeniu metody odwoływałaby się do nieistniejącej zmiennej. Jeśli zmienna lokalna metody typu final jest użyta w klasie wewnętrznej tej metody to tworzone jest prywatne pole w klasie danej metody i tworzony jest niejawny parametr w każdym konstruktorze tej klasy, które jest automatycznie inicjalizowane przy jego wywołaniu

Modyfikatory final abstract public private protected static * strictfp * - w tym przypadku static zmienia klasę wewnętrzną w klasę zagnieżdżoną

Anonymous Inner Class class Pomidorowa { public void zamieszaj() {} } class Ogorkowa { class Zupy { private Pomidorowa p = new Pomidorowa(); private Ogorkowa o = new Ogorkowa() { }; Klasa anonimowa to klasa lokalna bez nazwy tworzona w miejscu deklaracji. Tworzona klasa rozszerza klasę bazową!. Zwrócić uwagę na średnik na końcu deklaracji. Nie można stworzyć klasy anonimowej nieznanego typu.

class Ogorkowa { public void zamieszaj() {} } class Zupy { private Ogorkowa o = new Ogorkowa() { public void odcedz() {} }; void gotuj() { o.zamieszaj(); o.odcedz(); Q7, Czy ten kod jest poprawny? Nie można wywołać metody nie będącej częścią klasy bazowej

interface Zupa { void skladniki(); } abstract class Rosol implements Zupa { public abstract void zamieszaj(); class Zupy { private Rosol rosol = new Rosol() { public void zamieszaj() {} public void skladniki() {} }; private Zupa grzybowa = new Zupa() { Q8, Czy taki sposób tworzenia instancji interfejsu Zupa i klasy Rosół jest poprawna? Tak. Anonimową klasę można też utworzyć poprzez bezpośrednią implementację interfejsu. Mówi się, że klasa anonimowa jest implementatorem interfejsu. Ciekawostka: new Zupa() – normalnie nie można tworzyć instancji interfejsów – w tym jednak kontekście oznacza to utworzenie instancji klasy która implementuje interfejs Zupa. Składnia nie dopuszcza utworzenia klasy anonimowej, która implementuje wiele interfejsów. Nie dopuszcza też rozszerzenia jakiejś klasy i implementacji jednego interfejsu (np. p = new Klass implements IKlass {}; }

interface Operacja { int wykonaj(int a, int b); } class Dodaj implements Operacja { public int wykonaj(int a, int b) { return a + b; } } class Odejmij implements Operacja { public int wykonaj(int a, int b) { return a – b; } class Kalkulator { private int result = 0; void operacja(Operacja op, int liczba) { result = op.wykonaj(result, liczba); System.out.println("Result: " + result);

static public void main(String[] args) { new Kalkulator() public class Test { static public void main(String[] args) { new Kalkulator() .operacja(new Dodaj(), 7) .operacja(new Dodaj(), 5) .operacja(new Odejmij(), 1) .operacja(new Operacja() { public int wykonaj(int a, int b) return a * b; } }, 10); Klasę anonimową można zadeklarować jako przekazywany argument do metody. Zwracać uwagę na średniki.

Static Nested Classes Klasa statyczna zagnieżdżona nie jest klasą wewnętrzną! Jest statyczną klasą typu top-class. Ponieważ klasa jest statyczna, nie ma ŻADNYCH powiązań z klasą zewnętrzną. Tworzenie SNC wymaga użycia nazwy klasy zewnętrznej.

Do czego to się przydaje? lepsza organizacja kodu / enkapsulacja tworzenie nowych typów w miejscu ich użycia szybkie prototypowanie pozwalają tworzyć zgrabny / elegancki kod

Wady wzrasta liczba klas, którą musi załadować JVM duża liczba wewnętrznych klas może zaciemnić kod nie wszystkie IDE obsługują tak dobrze klasy wewnętrzne jak top klasy (refactoring / podpowiadanie). raczej tylko dla doświadczonych programistów

Domknięcia (closures)