Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałHalina Chmielewska Został zmieniony 6 lat temu
1
Klasy wewnętrzne. Praktyka użycia interfejsów i klas wewnętrznych
(c) Krzysztof Barteczko 2014
2
to klasa zdefiniowana wewnątrz innej klasy.
Klasy wewnętrzne - definicja Klasa wewnętrzna to klasa zdefiniowana wewnątrz innej klasy. class A { class B { .... } } Klasa B jest klasą wewnętrzną w klasie A. Klasa A jest klasą otaczającą klasy B. (c) Krzysztof Barteczko 2014
3
Klasa wewnętrzna a otaczająca
(c) Krzysztof Barteczko 2014
4
Właściwości klas wewnętrznych
(c) Krzysztof Barteczko 2014
5
Po co są klasy wewnętrzne?
(c) Krzysztof Barteczko 2014
6
(c) Krzysztof Barteczko 2014
Przykład (c) Krzysztof Barteczko 2014
7
(c) Krzysztof Barteczko 2014
Kod public class Car extends Vehicle { // ... private class FuelConsume implements ActionListener { @Override public void actionPerformed(ActionEvent e) { fuel -= 1; // odwolanie do pryw. składowej klasy otaczającej if (fuel == 0) stop(); } private Timer fuelTimer = new Timer(1000, new FuelConsume()); public Car start() { if (getState() == MOVING) return this; // nie można użyć start 2 razy pod rząd! if (fuel > 0) { super.start(); if (getState() == MOVING) // tylko jeśli udało się wystartować pojazd! fuelTimer.start(); // --- start Timera else error("Brak paliwa"); return this; public Car stop() { fuelTimer.stop(); super.stop(); public void crash(Vehicle v) { this.fuelTimer.stop(); if (v instanceof Car) ((Car) v).fuelTimer.stop(); super.crash(v); (c) Krzysztof Barteczko 2014
8
(c) Krzysztof Barteczko 2014
Test (c) Krzysztof Barteczko 2014
9
Odwołania do klasy wewnętrznej
Odwołanie do widocznej (np. publicznej) klasy wewnętrznej: NazwaKlasyOtaczającej.NazwaKlasyWewnętrznej Tworzenie obiektu niestatycznej klasy wewnętrznej wymaga zawsze istnienia obiektu klasy otaczającej. (c) Krzysztof Barteczko 2014
10
Anonimowe klasy wewnętrzne
(c) Krzysztof Barteczko 2014
11
Schematyczny przykład
Record jakisRekord; //.... db.add(jakisRekord); (c) Krzysztof Barteczko 2014
12
Anonimowy FuelConsumer
(c) Krzysztof Barteczko 2014
13
(c) Krzysztof Barteczko 2014
Uproszczenie Po co nam zmienna fuelConsumer? Przecież wszędzie tam, gdzie może wystąpić referencja może wystąpić wyrażenie new. Może zatem wystąpić jako drugi argument wyrażenia new, tworzacego timer. private Timer fuelTimer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { fuel -= 1; if (fuel == 0) stop(); } }); (c) Krzysztof Barteczko 2014
14
Uwagi nt anonimowych klas wewnętrznych
(c) Krzysztof Barteczko 2014
15
Lokalne klasy wenętrzne
(c) Krzysztof Barteczko 2014
16
Java7 Przykład: wyszukiwanie plików
Wobec katalogu można użyć metody listFiles z klasy File, która zwraca tablicę obiektów plikowych w nim zawartych. Używając metody listFiles z argumentem typu FileFilter możemy określić kryteria filtrowania wyniku według właściwości obiektów plikowych (np. otrzymać tylko listę plików o rozszerzeniu .java lub zmodyfikowanych po jakiejś dacie). FileFilter jest interfejsem, w którym zawarto jedną metodę boolean accept(File file). File dir = new File(...); Calendar c = Calendar.getInstance(); c.set(2013, 7, 22, 0, 0); final long time = c.getTimeInMillis(); File[] files = dir.listFiles( new FileFilter() { public boolean accept(File file) { return file.isFile() && file.getName().endsWith(".java") && file.lastModified() >= time; } }); Java7 (c) Krzysztof Barteczko 2014
17
Java7 Parametry to też zmienne lokalne
static File[] getFiles(String fromDir, final String ext, String afterDate) throws ParseException { final long time = new SimpleDateFormat("yyyy-MM-dd") .parse(afterDate) .getTime(); File[] files = new File(fromDir).listFiles( new FileFilter() { @Override public boolean accept(File f) { return f.isFile() && f.getName().endsWith(ext) && f.lastModified() >= time; } }); return files; (c) Krzysztof Barteczko 2014
18
Java8 Zmienne efektywnie finalne
W Javie w wersji 8 wprowadzono wygodne pojęcie zmiennej efektywnie finalnej (effectively final). Jest to taka zmienna, co do której kompilator może stwierdzić, że nie zmienia ona swoich wartości (np. nie występuje z lewej strony przypisań). Dzięki temu osłabiono wymaganie na dostęp do zmiennych lokalnych z anonimowych klas wewnętrznych: takie zmienne nie muszą być już deklarowane ze specyfikatorem final, ale muszą być efektywnie finalne. static File[] getFiles(String fromDir, String ext, String afterDate) throws ParseException { long time = // ... File[] files = new File(fromDir).listFiles( new FileFilter() { @Override public boolean accept(File f) { return f.isFile() && f.getName().endsWith(ext) && f.lastModified() >= time; } }); return files; Java8 (c) Krzysztof Barteczko 2014
19
Praktyczna użyteczność interfejsów i klas wewnętrznych
interfejsy kolekcyjne iterowalne obiekty niekolekcyjne wizytowanie drzew katalogowych (c) Krzysztof Barteczko 2014
20
w kategoriach interfejsów, a nie konkretnych klas
Interfejsy kolekcyjne Klasy kolekcyjne w Javie implementują odpowiednie interfejsy. Na przykład: klasy ArrayList i LinkedList - interfejs List, klasy HashSet, LinkedHashSet i TreeSet - interfejs Set. Interfejsy określają dostępne operacje na wyznaczanych przez nie strukturach danych, a wybór implementacji zależy od potrzeb naszego programu (rózne implementacje mają rózne właściwości). Gdy nasz program tworzy konkretne obiekty klas kolekcyjnych, to zawsze musimy dokonać takiego wyboru. Ale ważną rzeczą jest, by wszelkie inne działania na kolekcjach wykonywać w kategoriach interfejsów, a nie konkretnych klas Zwiększa to uniwersalność kodu. (c) Krzysztof Barteczko 2014
21
(c) Krzysztof Barteczko 2014
Przykład (c) Krzysztof Barteczko 2014
22
(c) Krzysztof Barteczko 2014
Interfejs Iterable (c) Krzysztof Barteczko 2014
23
Iterowalne obiekty niekolekcyjne
(c) Krzysztof Barteczko 2014
24
(c) Krzysztof Barteczko 2014
Realizacja class FromTo implements Iterable<Calendar> { private Calendar from = Calendar.getInstance(), to = Calendar.getInstance(); public FromTo(String fromString, String toString) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { from.setTime(df.parse(fromString)); to.setTime(df.parse(toString)); } catch (ParseException exc) { throw new IllegalArgumentException(exc.getMessage()); } public Iterator<Calendar> iterator() { return new Iterator<Calendar>() { Calendar current = Calendar.getInstance(), next = Calendar.getInstance(); { current.setTime(from.getTime()); current.add(Calendar.DATE, -1); public boolean hasNext() { next.setTime(current.getTime()); next.add(Calendar.DATE, 1); return next.compareTo(to) <= 0; public Calendar next() { if (!hasNext()) throw new NoSuchElementException(); current.add(Calendar.DATE, 1); return current; }; W Javie 8 interfejs Iterator zawiera domyślną metodę remove(), więc nie trzeba jej implementować. (c) Krzysztof Barteczko 2014
25
Wizytowanie drzew katalogowych
W klasie java.nio.file.Files znajdziemy użyteczną metodę statyczną: Path walkFileTree(Path startDir, FileVisitor visitor) która pozwala na rekurencyjne przeglądanie katalogów (poczynając od katalogu startDir) i wykonywanie operacji na ich elementach (plikach i podkatalogach). (c) Krzysztof Barteczko 2014
26
Metody interfejsu FileVisitor
(c) Krzysztof Barteczko 2014
27
(c) Krzysztof Barteczko 2014
Wyniki wizytowania (c) Krzysztof Barteczko 2014
28
Przykład wizytowania drzewa katalogowego
public class CountLines { private long count = 0; private PathMatcher matcher; private Path startDir; public CountLines(String startDir) { this.startDir = Paths.get(startDir); } public long of(String glob) throws IOException { matcher = FileSystems.getDefault().getPathMatcher("glob:*.java"); Files.walkFileTree(startDir, new SimpleFileVisitor<Path>() { public FileVisitResult visitFile(Path file, BasicFileAttributes a) { if (matcher.matches(file.getFileName())) { try { count += Files.readAllLines(file, Charset.defaultCharset()).size(); } catch (IOException exc) { System.out.println(exc); return FileVisitResult.CONTINUE; }); return count; public static void main(String[] args) throws IOException { long count = new CountLines("..").of("*.java"); System.out.println("Lines count: " + count); PathMatcher – regex lub glob SimpleFileVisitor daje standard, umozliwia wybór metod (c) Krzysztof Barteczko 2014
29
Pojęcie o lambda-wyrażeniach
(c) Krzysztof Barteczko 2014
30
(c) Krzysztof Barteczko 2014
Lambda – przykład 1 (c) Krzysztof Barteczko 2014
31
(c) Krzysztof Barteczko 2014
Lambda – przykład 2 (c) Krzysztof Barteczko 2014
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.