Typy generyczne w języku Java Samouczek Programisty

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

1/12

Typy generyczne w języku Java

Dzień dobry! Nadszedł czas na poznanie typów generycznych. Dowiesz się o
“szablonach” w języku Java, które pozwalają na tworzenie bardziej uniwersalnych
typów. Jest to wstęp, który pozwoli Ci dobrze zrozumieć kluczowy aspekt
standardowych kolekcji (“tablic na sterydach”) w języku Java. Każdy programista Javy
musi znać typy generyczne :) Zapraszam do artykułu!

© huntingglee

(https://www.flickr.com/photos/huntingglee/2222875354)

Strona główna

(http://www.samouczekprogramisty.pl/)

/ Typy generyczne w języku Java

Samouczkowy newsletter

To jest jeden z artykułów w ramach

darmowego kursu programowania w Javie

(http://www.samouczekprogramisty.pl/kurs-programowania-java)

. Proszę zapoznaj się z pozostałymi częściami,

mogą one być pomocne w zrozumieniu materiału z tego artykułu.

Czym są typy generyczne

W uproszczeniu można powiedzieć, że typy generyczne są “szablonami”. Dzięki typom generycznym możemy uniknąć niepotrzebnego
rzutowania. Ponadto przy ich pomocy kompilator jest w stanie sprawdzić poprawność typów na etapie kompilacji, oznacza to więcej błędów
wykrytych w jej trakcie .

Poza tym dzięki typom generycznym możemy konstruować bardziej złożone klasy, które możemy używać w wielu kontekstach, łatwiej
będzie Ci to zrozumieć na przykładzie.

Porównanie typów generycznych i standardowych

Znasz już zwykłe klasy i interfejsy, zostały one omówione we wcześniejszych artykułach. Klasy mają swoje atrybuty, których typy znasz
pisząc program.

1 znajomy lubi to

SamouczekProgra…

1481 polubienia

Polub tę stronę

Udostępnij

1

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

2/12

W przykładzie powyżej klasa

 AppleBox 

“wie” jakiego typu obiekt może przechowywać, jest to obiekt typu

 Apple 

. A co jeśli chcielibyśmy

zrobić analogiczną klasę dla owoców innego rodzaju? Oczywiście możemy stworzyć podobne pudełko jak w przykładzie poniżej:

Oba przykłady są jak najbardziej poprawne jednak występuje w nich duplikacja. Te same elementy, konstrukcje powielane są wielokrotnie.
Duplikacja w kodzie generalnie jest złą praktyką, należy jej unikać. Możemy zatem stworzyć kolejną klasę:

Z racji tego, że atrybut

 fruit 

jest typu

 Object 

możemy do niego przypisać zarówno instancję klasy

 Orange 

jak i

 Apple 

. Pojawia się jednak

pewien problem. Mianowicie jeśli chcemy pobrać atrybut

 fruit 

i przypisać go do zmiennej odpowiedniego typu musimy rzutować. Tego

typu konstrukcja może powodować błędy podczas wykonania programu i warto jej unikać. Z pomocą przychodzą typy generyczne. Proszę
spójrz na przykład poniżej.

public

class

Apple

{

}

public

class

AppleBox

{

private

Apple apple

;

public

AppleBox

(

Apple apple

)

{

this

.

apple

=

apple

;

}

public

Apple

getApple

()

{

return

apple

;

}

}

public

class

Orange

{

}

public

class

OrangeBox

{

private

Orange orange

;

public

OrangeBox

(

Orange orange

)

{

this

.

orange

=

orange

;

}

public

Orange

getOrange

()

{

return

orange

;

}

}

public

class

FruitBox

{

private

Object fruit

;

public

FruitBox

(

Object fruit

)

{

this

.

fruit

=

fruit

;

}

public

Object

getFruit

()

{

return

fruit

;

}

}

public

class

Main

{

public

static

void

main

(

String

[]

args

)

{

FruitBox fruitBox

=

new

FruitBox

(

new

Orange

());

Orange fruit1

=

(

Orange

)

fruitBox

.

getFruit

();

}

}

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

3/12

 public class BoxOnSteroids<T> 

to nic innego jak pierwsza linijka definicji klasy. Nowa tutaj jest konstrukcja z nawiasami. Oznacza ona

właśnie typ generyczny, który możemy parametryzować innym typem. Typ ten dostaje tymczasową nazwę, w tym przypadku

 T 

, której

używamy dalej w ciele klasy.

W trakcie tworzenia instancji obiektu

 BoxOnSteroids 

podajemy informację o typie, który chcielibyśmy wstawić w miejsce

 T 

. W naszym

przykładzie są to klasy

 Apple 

lub

 Orange 

. Dzięki takiej konstrukcji kompilator dokładnie wie jakiego typu obiekt zostanie zwrócony przez

metodę

 getFruit 

w związku z tym rzutowanie nie jest konieczne .

Klasy generyczne i parametryzowanie

Wspomniałem wcześniej, że klasy generyczne są szablonami dla nowych klas. W uproszczeniu można powiedzieć, że parametry klasy
generycznej są elementami uzupełnianymi w szablonie.

Spróbuję opisać to bardziej obrazowo. Szablon to foremka do wycinania ciastek. Tej foremki możemy użyć do wycięcia wielu ciastek. Każde
z nich możemy ozdobić w inny sposób. To w jaki sposób ciastko jest ozdobione jest parametrem tego szablonu:

Definicja klasy generycznej

Klasę generyczną definiujemy w następujący sposób

Zauważ, że w nawiasach

 <> 

możemy umieścić więcej niż jeden parametr. Chociaż zgodnie ze specyfikacją języka Java możesz użyć

dowolnej nazwy która nadaje się na nazwę zmiennej istnieje konwencja nazewnicza sugerująca nazwy parametrów. Zwyczajowo do tego
celu używa się wielkich liter

 T 

,

 K 

,

 U 

,

 V 

,

 E 

.

W miejsce parametrów możemy wstawić dowolny obiekt, nie może to jednak być typ prosty. Innymi słowy

 Integer 

jest w porządku,

 int 

powoduje błąd.

Instancja klasy generycznej

Skoro już wiemy jak zdefiniować klasę generyczną przydałoby się stworzyć jej instancję, żeby w końcu jej użyć :). Linijka poniżej tworzy
instancję klasy generycznej

 BoxOnSteroids 

, która parametryzowana jest typem

 Orange 

.

public

class

BoxOnSteroids

<

T

>

{

public

T fruit

;

public

BoxOnSteroids

(

T fruit

)

{

this

.

fruit

=

fruit

;

}

public

T

getFruit

()

{

return

fruit

;

}

}

public

class

Main

{

public

static

void

main

(

String

[]

args

)

{

BoxOnSteroids

<

Apple

>

appleBox

=

new

BoxOnSteroids

<

Apple

>(

new

Apple

());

BoxOnSteroids

<

Orange

>

orangeBox

=

new

BoxOnSteroids

<

Orange

>(

new

Orange

());

Orange fruit

=

orangeBox

.

getFruit

();

}

}

2

public

class

CookieCutter

<

T

>

{

private

T glaze

;

}

class

Name

<

T1

,

T2

,

...,

Tn

>

{

/* body */

}

BoxOnSteroids

<

Orange

>

orangeBox

=

new

BoxOnSteroids

<

Orange

>(

new

Orange

());

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

4/12

Zauważ, że i tutaj występuje pewna duplikacja. Zarówno przy określaniu typu zmiennej jak i przy wywołaniu konstruktora powtarzamy klasę

 Orange 

. Nie jest to konieczne. Jeśli kompilator jest w stanie “wywnioskować” jaki typ powinien być użyty możemy go pominąć przy

konstruktorze.

Zagnieżdżone typy generyczne

Możesz też tworzyć instancje typów generycznych, które są bardziej skomplikowane. Przykład poniżej pokazuje klasę

 Pair 

, która

parametryzowana jest dwoma innymi typami.

Java pozwala na to aby tworząc instancję typu generycznego parametryzować go innym typem generycznym. Brzmi to skomplikowanie,
mam nadzieję, że przykład pomoże Ci to zrozumieć:

W przykładzie tym tworzony jest obiekt klasy

 Pair 

, który parametryzowany jest klasami

 BoxOnSteroids<Orange> 

i

 BoxOnSteroids<Apple> 

.

Typy generyczne nie rozwiązują wszystkich problemów

Typy generyczne zostały wprowadzone w wersji Javy 1.5. Nie były dostępne od początku jej istnienia. Zatem istnieją sytuacje, w których
nawet ich stosowanie może prowadzić do wystąpienia błędów w trakcie wykonywania programu. Proszę spójrz na przykład poniżej:

W przykładzie tym tworzona jest instancja klasy generycznej

 BoxOnSteroids 

bez wyspecyfikowania klasy, która znajduje się “w środku”.

Następnie tę instancję przypisujemy do zmiennych typu

 BoxOnSteroids<Apple> 

i

 BoxOnSteroids<Orange> 

. O ile w pierwszym przypadku typ

owocu trzymanego w środku się zgadza to ostatnia linia nie jest poprawna – generuje błąd typu

 ClassCastException 

. Obiekt typu

 Apple 

jest

rzutowany przez kompilator do typu

 Orange 

.

Słowo kluczowe

extends

To słowo kluczowe ma zastosowanie także w przypadku typów generycznych. Dzięki niemu możemy ograniczyć zestaw klas którymi
możemy parametryzować nasz typ generyczny. Omówmy to na przykładzie:

BoxOnSteroids

<

Orange

>

orangeBox

=

new

BoxOnSteroids

<>(

new

Orange

());

public

class

Pair

<

T

,

S

>

{

private

T first

;

private

S second

;

public

Pair

(

T first

,

S second

)

{

this

.

first

=

first

;

this

.

second

=

second

;

}

public

T

getFirst

()

{

return

first

;

}

public

S

getSecond

()

{

return

second

;

}

}

Pair

<

BoxOnSteroids

<

Orange

>,

BoxOnSteroids

<

Apple

>>

pairOfBoxes

=

new

Pair

<>(

new

BoxOnSteroids

<>(

new

Orange

()),

new

BoxOnSteroids

<>(

new

Apple

())

);

BoxOnSteroids boxWithoutType

=

new

BoxOnSteroids

(

new

Apple

());

BoxOnSteroids

<

Apple

>

boxWithApple

=

boxWithoutType

;

BoxOnSteroids

<

Orange

>

boxWithOrange

=

boxWithoutType

;

Apple apple

=

boxWithApple

.

getFruit

();

Orange orange

=

boxWithOrange

.

getFruit

();

// ClassCastException

3

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

5/12

Jak widzisz przykład definiuje prosty interfejs

 Figure 

i klasę

 Circle 

, która go implementuje. Następnie definiujemy klasę

 BoxForFigures 

,

która jest generyczna i może być parametryzowana przez typy dziedziczące/implementujące

 Figure 

.

Dzięki takiemu zapisowi kompilator pozwoli nam stworzyć instancję

 BoxForFigures<Circle> circleBox 

jednak zacznie się buntować przy

 BoxForFigures<Apple> appleBox 

(

 Apple 

nie implementuje interfejsu

 Figure 

).

Kolejną zaletą używania tego słowa kluczowego jest możliwość wywoływania metod na obiekcie typu parametryzowanego. W przykładzie
powyżej wiemy że

 T 

jest czymś co implementuje

 Figure 

więc musi mieć metody dostępne w tym interfejsie. Właśnie z tego powodu w

metodzie

 getElementName 

możemy wywołać metodę

 getName 

z tego interfejsu.

Dziedziczenie typów generycznych

Tutaj należy się dodatkowe zdanie wyjaśnienia poparte prostym przykładem. Proszę spójrz na początek na klasy

 Rectangle 

i

 Square 

poniżej:

Jak wiesz każda klasa w języku Java dziedziczy po klasie

 Object 

(bezpośrednio, bądź pośrednio). W naszym przykładzie bezpośrednio po

klasie

 Object 

dziedziczą klasy

 Rectangle 

,

 BoxForFigures<Rectangle> 

i

 BoxForFigures<Square> 

. Natomiast

 Square 

dziedziczy po

 Rectangle 

.

public

interface

Figure

{

String

getName

();

}

public

class

Circle

implements

Figure

{

public

String

getName

()

{

return

"circle"

;

}

}

public

class

BoxForFigures

<

T

extends

Figure

>

{

private

T element

;

public

BoxForFigures

(

T element

)

{

this

.

element

=

element

;

}

public

T

getElement

()

{

return

element

;

}

public

String

getElementName

()

{

return

element

.

getName

();

}

}

BoxForFigures

<

Circle

>

circleBox

=

new

BoxForFigures

<>(

new

Circle

());

BoxForFigures

<

Apple

>

appleBox

;

// complilation error

public

class

Rectangle

implements

Figure

{

public

String

getName

()

{

return

"rectangle"

;

}

}

public

class

Square

extends

Rectangle

{

public

String

getName

()

{

return

"square"

;

}

}

4

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

6/12

Dziedziczenie typów generycznych.

Ma to swoje konsekwencje widoczne w przykładzie poniżej:

Dzięki takiemu schematowi dziedziczenia do referencji typu

 Rectangle 

możemy przypisać obiekt

 Square 

. Jednak próba przypisania obiektu

 BoxForFigures<Square> 

do referencji

 BoxForFigures<Rectangle> 

powoduje błąd kompilacji.

Jednak podobnie jak w przypadku zwykłych klas, klasy generyczne także mogą dziedziczyć po innych klasach. W szczególności mogą
także dziedziczyć po klasach generycznych.

W naszym przykładzie klasa

 FancyBox 

dziedziczy po

 StandardBox 

, widoczne jest to na diagramie poniżej.

Rectangle rectangle

=

new

Square

();

BoxForFigures

<

Rectangle

>

rectangleBox

=

new

BoxForFigures

<

Square

>(

new

Square

());

// compilation error

class

StandardBox

<

T

>

{

public

T object

;

public

StandardBox

(

T object

)

{

this

.

object

=

object

;

}

}

public

class

FancyBox

<

T

>

extends

StandardBox

<

T

>

{

public

FancyBox

(

T object

)

{

super

(

object

);

}

public

void

saySomethingFancy

()

{

System

.

out

.

println

(

"our "

+

object

+

" is cool!"

);

}

}

public

class

Main

{

public

static

void

main

(

String

[]

args

)

{

FancyBox

<

String

>

box

=

new

FancyBox

<>(

"something"

);

box

.

saySomethingFancy

();

}

}

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

7/12

Dziedziczenie typów generycznych

Metody z generycznymi argumentami – wildcard

FancyBox<?>

Pisząc metody, które jako argumenty przyjmują typy generyczne nie zawsze chcesz dokładnie specyfikować typ. W takim wypadku z
pomocą przychodzi znak

 ? 

, który może akceptować różne typy.

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

8/12

Jak widzisz w przykładzie powyżej metoda method1 może akceptować różne klasę

 FancyBox 

parametryzowaną dowolnym typem.

Przypisanie wartości

Ma to jednak swoje konsekwencje. Klasa, która parametryzowana jest

 ? 

nie przyjmie żadnych obiektów poza

 null 

. Przykład poniżej

zakończy się błędem kompilacji:

FancyBox<? extends Figure> “upper bound”

Znak

 ? 

może występować także w połączeniu ze słówkiem kluczowym

 extends 

. W takim przypadku możesz ograniczyć akceptowane typy

“z góry”. W przykładzie poniżej metoda akceptuje jedynie instancje

 FancyBox 

, które parametryzowane są klasami dziedziczącymi po

 Figure 

.

W przykładzie tym możesz także zobaczyć, że typ

 FancyBox<Figure> 

jest bardziej restrykcyjny niż

 FancyBox<? extends Figure> 

. W

konsekwencji próba wywołania

 method3 

z argumentem innego typu niż

 FancyBox<Figure> 

skutkuje błędem kompilacji.

Przypisanie wartości

Podobnie jak w przypadku

 ? 

tutaj także są ograniczenia dotyczące przypisywania wartości. Spójrz jeszcze raz na przykład:

Skoro wewnątrz metody parametr

 box 

może mieć zarówno typ

 FancyBox<Square> 

jak i

 FancyBox<Circle> 

(jak i wiele innych) kompilator nie

może pozwolić na wstawienie tam obiektu innego niż

 null 

. Nie może tego zrobić bo nie wie jakiego typu obiekty przechowywane są w

 box 

.

private

static

void

method1

(

FancyBox

<?>

box

)

{

Object object

=

box

.

object

;

System

.

out

.

println

(

object

);

}

private

static

void

plainWildcard

()

{

method1

(

new

FancyBox

<>(

new

Object

()));

method1

(

new

FancyBox

<>(

new

Square

()));

method1

(

new

FancyBox

<>(

new

Apple

()));

}

FancyBox

<?>

box

=

new

FancyBox

<>(

"object"

);

box

.

object

=

null

;

// box.object = "xxx"; // compilation error

private

static

void

method2

(

FancyBox

<?

extends

Figure

>

box

)

{

Figure figure

=

box

.

object

;

System

.

out

.

println

(

figure

);

}

private

static

void

method3

(

FancyBox

<

Figure

>

box

)

{

Figure figure

=

box

.

object

;

System

.

out

.

println

(

figure

);

}

private

static

void

upperBoundWildcard

()

{

FancyBox

<

Figure

>

fancyFigureBox

=

new

FancyBox

<>(

new

Circle

());

FancyBox

<

Circle

>

fancyCircleBox

=

new

FancyBox

<>(

new

Circle

());

FancyBox

<

Square

>

fancySquareBox

=

new

FancyBox

<>(

new

Square

());

method2

(

fancyFigureBox

);

method2

(

fancyCircleBox

);

method2

(

fancySquareBox

);

// method3(fancySquareBox); // compilation error

}

private

static

void

method2

(

FancyBox

<?

extends

Figure

>

box

)

{

Figure figure

=

box

.

object

;

System

.

out

.

println

(

figure

);

// box.object = null;

// box.object = new Square(); // compilation error

}

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

9/12

FancyBox<? super Rectangle> “lower bound”

Poza ograniczeniem “z góry” możesz także ograniczyć akceptowalne typy “z dołu”. W przykładzie poniżej metoda akceptuje wyłącznie
argumenty typu

 FancyBox<Object> 

,

 FancyBox<Figure> 

i

 FancyBox<Rectangle> 

.

Zauważ, ze w niektórych miejscach nie ma potrzeby podawania typu generycznego. Samo

 <> 

wystarczy, kompilator jest w stanie

wywnioskować jakiego typu może się tam spodziewać. Typy generyczne są skomplikowane. Jeśli aktualnie masz mętlik w głowie nie
przejmuj się, przeczytaj artykuł jeszcze raz, przejrzyj przykłady. Zrozumienie przyjdzie z doświadczeniem.

Przypisanie wartości

Wyżej wspomniałem, że przy ograniczeniu z dołu kompilator wie czego może się spodziewać. W przykładzie:

Parametr

 box 

może być typu

 FancyBox<Object> 

,

 FancyBox<Square> 

i

 FancyBox<Rectangle> 

. Zatem w tym przypadku do pola

 box.object 

można przypisać

 null 

i każdy obiekt, który dziedziczy po

 Rectangle 

.

Typy generyczne są skomplikowane

Nie zostały one dodane do Javy od samego początku. W związku z tym, że twórcy chcieli zachować kompatybilność wstecz istnieje wiele
kruczków, które nie są trywialne. Pominąłem w artykule np. “type erasure” czy generyczne metody, które nie są istotne na początku. Jeśli
jesteś nimi zainteresowany odsyłam do materiałów dodatkowych.

Materiały dodatkowe

Wszystkie przykłady użyte w tym artykule dostępne są na githubie

(https://github.com/SamouczekProgramisty/KursJava/tree/master/13_typy_generyczne/src/main/java/pl/samouczekprogramisty/kursjava/generics)

. Poniżej zebrałem dla

Ciebie zestaw dodatkowy materiałów, jeśli chciałbyś poszerzyć swoją wiedzę na temat typów generycznych w języku Java.

https://docs.oracle.com/javase/tutorial/java/generics/index.html

(https://docs.oracle.com/javase/tutorial/java/generics/index.html)

https://docs.oracle.com/javase/tutorial/extra/generics/index.html

(https://docs.oracle.com/javase/tutorial/extra/generics/index.html)

https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5

(https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5)

https://pl.wikipedia.org/wiki/Programowanie_uog%C3%B3lnione

(https://pl.wikipedia.org/wiki/Programowanie_uog%C3%B3lnione)

Podsumowanie

Nie jest to oczywiście kompletny artykuł dotyczący typów generycznych w Javie. Pominięte zostały aspekty wymazywania typów czy
bardziej szczegółowe informacje dotyczące użycia ?. Jeśli któryś fragment jest dla Ciebie nie do końca zrozumiały daj znać, postaram się
rozszerzyć artykuł o dodatkowe przykłady i opisy.

private

static

void

method4

(

FancyBox

<?

super

Rectangle

>

box

)

{

box

.

object

=

new

Square

();

// box.object = new Circle(); // compilation error

}

private

static

void

lowerBoundWildcard

()

{

FancyBox

<

Rectangle

>

fancyRectangleBox

=

new

FancyBox

<>(

new

Rectangle

());

FancyBox

<

Figure

>

fancyFiguraBox

=

new

FancyBox

<>(

new

Rectangle

());

FancyBox

<

Object

>

fancyObjectBox

=

new

FancyBox

<>(

new

Object

());

method4

(

fancyRectangleBox

);

method4

(

fancyFiguraBox

);

method4

(

fancyObjectBox

);

// FancyBox<Square> fancySquareBox = new FancyBox<>(new Square());

// method4(fancySquareBox); // compilation error

}

private

static

void

method4

(

FancyBox

<?

super

Rectangle

>

box

)

{

box

.

object

=

null

;

box

.

object

=

new

Rectangle

();

box

.

object

=

new

Square

();

// box.object = new Object(); // compilation error

}

5

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

10/12

ZOSTAW KOMENTARZ

18 Komentarzy

samouczekprogramisty

Zaloguj

1

Udostępnij

Sortuj według najlepszych

ZALOGUJ SIĘ ZA POMOCĄ

ALBO ZAREJESTRUJ W DISQUS

Nazwa

Dołącz do dyskusji...

?

Odpowiedz

Łukasz Chojnowski

miesiąc temu

Znalazłem kilka zadań na typy generyczne. Prośba o analizę i uwagi (zwłaszcza zadania 4-6), bo mam tam błędy i nie bardzo wiem czemu
tak jest. Link:

https://github.com/lukasz-c...

△ ▽

Odpowiedz

Marcin Pietraszek

miesiąc temu

samouczek

> Łukasz Chojnowski

Pamiętaj, że liczby całkowite mogą być reprezentowane przez wiele typów, na przykład

Integer

,

Byte

czy

Long

.

Przeczytaj artykuł jeszcze raz. Uzupełniłem go o fragmenty, które powinny odpowiedzieć na Twoje pytania dotyczące zadań 4-6.

△ ▽

Odpowiedz

Łukasz Chojnowski

miesiąc temu

> Marcin Pietraszek

Poprawione i działa. Poprawki scommitowane w linku w poprzedniej wiadomości

△ ▽

scina

miesiąc temu

W jaki sposób pisać kod z przykładów, czy wszystkie przedstawione klasy mają być w jednym pliku tak jak są prezentowane, czy każda w
osobnym. Bo jeśli umieszczam klasy w jednym pliku, to muszę zagnieździć w klasie pliku i nadać parametr static. Jak to pisać i gdzie jest
mój błąd.

public class FruitBox {
private Object fruit;

public FruitBox(Object fruit) {
this.fruit = fruit;
}

public Object getFruit() {
return fruit;
}
}

public class Main {
public static void main(String[] args) {
FruitBox fruitBox = new FruitBox(new Orange());

Poleć

Udostępnij ›

Udostępnij ›

Udostępnij ›

Na koniec mam do Ciebie prośbę. Proszę podziel się artykułem ze swoimi znajomymi, którzy mogą być zainteresowani tematem
programowania. Zależy mi na dotarciu do jak największej liczby czytelników. Jeśli nie chcesz ominąć żadnego kolejnego artykułu polub nas
na Facebooku :) Do następnego razu!

1. Mała dygresja. Każdy błąd w kodzie kosztuje. Ktoś w końcu płaci za pracę testerów, programistów, administratorów. Im wcześniej wykryjemy błąd tym tańsze jest jego naprawienie.

Poprawienie programu działającego na środowisku produkcyjnym może być bardzo drogie. Wykrywanie błędów w trakcie kompilacji, chociaż może być frustrujące dla programisty
jest najtańszym rozwiązaniem :) 

2. W praktyce rzutowanie tam występuje jednak jest wykonywane automatycznie przez kompilator generujący bytecode. 

3. Tu właśnie objawia się to automatyczne rzutowanie generowane przez kompilator 

4. W rzeczywistości, po skompilowaniu powstanie jeden plik class z klasą

 BoxForFigures 

5. Twórcom zależało na tym aby programy napisane w starej wersji Javy mogły być uruchamiane na najnowszych wersjach maszyny wirtualnej. 

Dodaj mnie do newslettera

Kategorie:

Kurs programowania Java

Ostatnia aktualizacja: March 26, 2016

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

11/12

Odpowiedz

(

g ());

Orange fruit1 = (Orange) fruitBox.getFruit();
}
}

△ ▽

Odpowiedz

Marcin Pietraszek

miesiąc temu

samouczek

> scina

W języku Java jażdy z plików

java

może zawierać wyłącznie jedną publiczą klasę (pomijam

klasy wewnętrzne

). Co więcej nazwa

pliku musi odpowiadać nazwie klasy.

Polecam Ci zacząć od wcześniejszych artykułów, jak opanujesz podstawy zabierz się za bardziej zaawansowane elementy.

△ ▽

Odpowiedz

scina

miesiąc temu

> Marcin Pietraszek

Wkleiłem kod specjalnie, bo sugeruje że wszystko jest w jednym pliku. Odczytuje z kodu, że nazwą pliku i klasą główną jest
Main i jego metoda statyczna. Jednak reszta kodu z klasami z przykładu jest umieszczona poza tą klasa. Dlatwgo się pytam
gdzie te klasy umieszczać, nowa klasa nowy plik, czy jako klasę wewnetrzna z parametrem static?

△ ▽

Odpowiedz

Marcin Pietraszek

miesiąc temu

samouczek

> scina

Odpowiadając najprościej, bez wdawania się w dyskusję - podzieliłbym to na osobne pliki. Dokładnie tak jak w
zrobiłem to w kodzie na

githubie

.

△ ▽

Odpowiedz

scina

miesiąc temu

> Marcin Pietraszek

Dzięki, nie mogłem znaleźć nigdzie linku do do github, teraz mogę podejrzeć kod i znaleźć błędy. Dzięki. Ja zrobiłem
to na klasach wewnętrznych statycznych. Pozdrawiam

△ ▽

Odpowiedz

Marcin Pietraszek

miesiąc temu

samouczek

> scina

Na tym etapie kursu przykłady w artykule zakładają, że pierwsze etapy są już zrobione. W tych pierwszych etapach
dowiedziałbyś się o tym co napisałem wyżej :).

△ ▽

Odpowiedz

scina

miesiąc temu

> Marcin Pietraszek

Oczywiście, wrócę do poprzednich zagadnień, bo nie wszystko pamiętam, jednak mi chodziło o konwencję pisania
kodu z przykładów, nie widząc całości nie wiedziałem które klasy są w osobnym pliku, a które są wewnętrzne.

△ ▽

Odpowiedz

Dyrek Encki

5 miesięcy temu

Proszę wyjaśnij co to znaczy parametryzować czyli nabywać wszystkie cechy wskazane przez TYP określony w <> (zmienne, metody etc.)
?

△ ▽

Odpowiedz

Marcin Pietraszek

5 miesięcy temu

samouczek

> Dyrek Encki

Hmm, nie mogę znaleźć takiego określenia w artykule. Możesz wskazać akapit, o który Ci chodzi? Możliwe, że napisałem coś
niejasno i będę musiał to przepisać.

△ ▽

Odpowiedz

Dyrek Encki

5 miesięcy temu

> Marcin Pietraszek

Może inaczej zapytam. Co oznacza w przypadku generyków parametryzowanie ? Czy jeżeli podam jakąś klasę/obiekt jako
parametr w klasie generycznej to czy oznacza to że przekazuje też dostęp do jej pól, metod, konstruktorów etc.? Jeżeli tak to
jaka jest różnica czy ja będę dziedziczył czy zrobię generyka ? Rozumiem, że jest to pewna forma poliformizmu, ale nie
jestem tego wszystkiego pewny.

△ ▽

Odpowiedz

Marcin Pietraszek

5 miesięcy temu

samouczek

> Dyrek Encki

Dodałem krótki akapit o

parametryzowaniu

.

To, że utworzysz klasę, która jest parametryzowana typem nie ma nic wspólnego z dziedziczeniem. Dziedziczenie
typów generycznych opisałem w

osobnym punkcie

.

Główna różnica jest taka, że przy dziedziczeniu niektóre

modyfikatory dostępu

pozwalają na dostęp do danego pola

klasom pochodnym.

△ ▽

Odpowiedz

Adam Zarzecki

10 miesięcy temu

Super wyjaśnione , najbardziej podobał mi się odcinek z rzutowaniem i zdjęciem w tle... (IF == YOU ) System.out.println("KNOW WHAT I
MEAN");

△ ▽

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

Udostępnij ›

background image

3.06.2018

Typy generyczne w języku Java - Samouczek Programisty

http://www.samouczekprogramisty.pl/typy-generyczne-w-jezyku-java/

12/12

Referencja, sterta i garbage collector – obiektów w Javie ciąg
dalszy

5 komentarzy

rok temu

Tomasz Kubicz

— Dzięki bardzo za kurs! Co prawda miałem już

okazję poznać podstawy Javy, wykonać jakiś swój pierwszy projekt w
Springu, ale wszystko poszło na kilka miesięcy w …

Konwersja i rzutowanie w języku Java

20 komentarzy

rok temu

Marcin Pietraszek

— Proszę przeczytaj artykuł o typach prostych.

Wspomniałem w nim jak powinien wyglądać literał dla typu float.Liczba
3.42 ma typ double, dlatego nie możesz jej …

Adnotacje w języku Java

3 komentarzy

rok temu

Łukasz Chojnowski

— Nie było specjalnie trudno. Zrobione. Efekt:

https://github.com/lukasz-c...

Podstawy złożoności obliczeniowej - Samouczek Programisty

10 komentarzy

7 miesięcy temu

Marcin Pietraszek

— Szczerze mówiąc nie wiem co masz na myśli

mówiąc o końcowym wyniku. Można powiedzieć, że n to rozmiar
problemu - dla wszystkich n większych od n0 g(n) jest …

TAKŻE NA

SAMOUCZEKPROGRAMISTY

Odpowiedz

Marcin Pietraszek

10 miesięcy temu

samouczek

> Adam Zarzecki

Cięszę się, że artykuły Ci się podobają. Jeśli jakiegoś tematu brakuje Ci na blogu, daj znać - postaram się pomóc.

△ ▽

Odpowiedz

Adam Zarzecki

10 miesięcy temu

> Marcin Pietraszek

hmm ... no Marcin mi dużo pomogła twoja strona. Na pewno oszczędziłem sporo czasu . Czego brakuje? hm...
mi przede wszystkim brakuje zadań z przykładowymi rozwiązaniami. Mogłbyś zrobic na koniec jakiś test w postaci 10 zadań :)
... a jeśli chodzi o tematy to zamiesciłeś dużo konkretow

△ ▽

Odpowiedz

Marcin Pietraszek

10 miesięcy temu

samouczek

> Adam Zarzecki

Pomyślę nad takim testem, może rzeczywiście jest to dobry pomysł. Jeśli chodzi o same zadania z rozwiązaniami to
na blogu jest ich całkiem sporo :). Zadania mają różny stopień trudności, na pewno znajdziesz coś dla siebie. Poza
zadaniami pod większością artykułów zebrałem inne na tych stronach:

http://www.samouczekprogram...

+

http://www.samouczekprogram...

△ ▽

Subskrybuj

Dodaj Disqus do swojej strony Dodaj DisqusDodaj

d

Disqus' Privacy Policypolityką prywatnościPrywatność

🔒

Udostępnij ›

Udostępnij ›

Udostępnij ›


Wyszukiwarka

Podobne podstrony:
Mysl w jezyku Java Nauka programowania
Mysl w jezyku Java Nauka programowania mysjav
Mysl w jezyku Java Nauka programowania
Programowanie współbieżne i rozproszone w języku Java stpiczynski
Efektywne Programowanie W Języku Java
Java, Programowanie W Jezyku Java
Efektywne programowanie w jezyku Java jappjp
Programowanie w jezyku Java
Efektywne programowanie w jezyku Java jappjp
Efektywne programowanie w jezyku Java 2
Programowanie w jezyku Java Zbior zadan z p odpowiedziami 2
Efektywne programowanie w jezyku Java 2
informatyka programowanie w jezyku java zbior zadan z p odpowiedziami wieslaw rychlicki ebook
Programowanie w jezyku Java Zbior zadan z p odpowiedziami
Programowanie w jezyku Java Zbior zadan z p odpowiedziami

więcej podobnych podstron