Obiektowość w Javie i Pythonie

0

Złoty Młot: "Do tego Java nie jest w pełni obiektowa jak Ruby czy Python". Na taki cytat trafiłem na forum, czy rzeczywiście Python jest "bardziej obiektowy" od Javy?

1

Java jest bardziej obiektowa, bo silniej wspiera enkapsulację.

2

Co dla ciebie oznacza "bardziej obiektowy" ?

0
scibi92 napisał(a):

Java jest bardziej obiektowa, bo silniej wspiera enkapsulację.

Hm..., nie uznam tego za wystarczające, encapsulacja to tylko jedna z cech obiektowości mozna powiedzieć, że jest to feature, a nie coś co jest wymagane do programowania obiektów.

@Shadoow: Właśnie dałem to w cudzysłów, ale chodzi o to, jak Java jest nie w pełni obiektowa w porównianiu z Pythonem.

4
scibi92 napisał(a):

Java jest bardziej obiektowa, bo silniej wspiera enkapsulację.

Czyli jak zwykle javascript wygrywa bo ma jeszcze silniejszą enkapsulację :-) od Javy.

0

W Javie liczby zdaje się nie są obiektami (tylko mogą być pakowane w obiekty, podobnie jak w JS), w Pythonie nawet liczby są w pełni obiektami.

Java jest bardziej obiektowa, bo silniej wspiera enkapsulację.

Enkapsulację którą i tak wszyscy łamią, bo tworzą gettery/settery na zapas do każdej klasy XD

Poza tym Java ssie w pozostałych aspektach OOP, podobnie jak C# czy C++, gdzie nie da się nawet wysłać normalnie komunikatu do obiektu (jedną z cech OOP jest właśnie to, że są obiekty, i można do nich wysyłać komunikaty w runtime).

Jak widzę projekty oparte o message passing w Javie/C#/C++ (choćby używające modnego wzorca event sourcing), to zawsze widzę potworne ilości boilerplate'u, potrzebne do zaemulowania czegoś, co w językach bardziej obiektowych (choćby Smalltalku, Ruby, czy nawet w JavaScript*) jest o wiele prostsze.

* mimo, że JavaScript też w pełni obiektowy nie jest.

0

Java ma fajną obiektówkę bo taką prostą i wszystko w składni a nie w jakichś sztuczkach jak w JS.
To że nie wszystko jest w niej obiektem to jest wada, ale można z tym żyć.
Gorzej jak masz napisać odpowiednią klasę generyczną - ale już nad tym pracują: http://tinyurl.com/zhjfayl

W Javie można też dobrać się do prywatnych pól i metod przez refleksje.

Wg Wiki Python jest "czystym" językiem obiektowym a Java "w pełni obiektowym"...
http://tinyurl.com/y7fckkv6

Ponoć lepiej to wygląda w Kotlinie, gdzie wszystko jest obiektem - jeśli komuś tego brakuje:
https://kotlinlang.org/docs/reference/basic-types.html

1
vpiotr napisał(a):

Ponoć lepiej to wygląda w Kotlinie, gdzie wszystko jest obiektem - jeśli komuś tego brakuje:
https://kotlinlang.org/docs/reference/basic-types.html

Tak samo w Scali. Właśnie przesiadki między Scalą a Javą pokazują dziury w Javie. (dziś niechcący zrobiłem porównanie dwóch Integerów przez == w każdym normalnym języku działa... a w javie... (dobrze, że IntelliJ krzyczał od razu).

0

@LukeJL: bo to zależy od tego czy coś jest jakimś pojemnikiem na dane np. modelem formularza, czy np. obiektem logiki. Jak tworze beany w Springu to korzystam z wstrzykywania interfejsów przez konstruktor i nie ma żadnych getterów tylko rzeczywiste metody zgodne z OOP np. UserRepository.findbyUsername(String username)

0

Gdyby java nie miała zablokowanych przeciążonych operatorów, to zrobiło by się od ręki, nową klasę typu auto, która by przeciążała operator = i by auto-typował.
Ale też lepiej jakby to było zatwierdzone przez jave.

W samej klasie object, też mogło by się przydać kilka ulepszeń i też by się przydał interpreter javy, ale oficjalny.

Ale tak ogólnie to ucząc się obiektówki za pomocą javy, to jest to najlepsza i najłatwiejsza forma nauki.
Inne języki też mają dobre OOP, ale dopiero od javy, mój poziom obiektowego programowania trochę się podniósł, sporo można się nauczyć, co by się nie znało, nie programując w tym języku.

Python też jest dobry w tym, więc warto znać oba :)

0

@LukeJL: bo to zależy od tego czy coś jest jakimś pojemnikiem na dane

Dla mnie to już wtedy nie jest obiektówka, tylko zwykłe struktury danych, które przez przypadek są obiektami, a tak naprawdę równie dobrze mogłyby być w jakiejś innej strukturze danych. Bo akurat dany język tak to zaimplementował, w JS też się robi często obiekty, których się używa bardziej jak struktur w C++ a nie jak obiekty w stylu OOP.

Ale wtedy nie ma co się bawić w gettery/settery tylko lepiej walić wszystko publicznie, jeśli faktycznie odchodzimy od OOP i działamy bardziej na zbiorach danych, a nie na obiektach (nie ma w tym nic złego zresztą, żeby wykorzystywać nieobiektowe struktury danych).

1

Dla mnie kwintesencją enkapsulacji w javie jest taka linijka (typowa dla JPA/hibernate):

group.getUsers().add(new User() );

Można żyć z mutowalnością.
Można żyć z seterami.

Ale pomysł, że aby sprawdzić kto na zmienił naszą grupę muszę poszukać po geterach to już szatański.

0

"Pełna obiektowość" to pojęcie dość enigmatyczne. W Javie 8 każda metoda jest obiektem dzięki Method References - metody można przekazywać jako parametry wprost, bez opakowywania w lambdę czy cokolwiek innego. (dla ciekawskich: lambdy w Javie 8 są zaimplementowane tak, że kompilator Javy tworzy nową ukrytą metodę zawierającą ciało lambdy, a potem w miejsce lambdy wstawia method reference do nowo utworzonej metody)

Cały dramat z prymitywami w zasadzie sprowadza się do tego, że jeśli mamy język w którym prymitywy mają metody to możemy napisać np:
5.max(6)
a w Javce trzeba klepnąć:

import static java.lang.Math.max

max(5, 6)

Reszta to jeszcze mniejsze detale. Nota bene: w Pythonie stosuje się składnię max(5, 6)

0

W Pythonie zdaje się (nie pisałem więcej niż parę linijek kodu, więc mogę się mylić) możesz dziedziczyć z wielu klas, a w Javie się nie da, więc może to jest ta "pełna obiektowość".
Podobnie w Javie nie uświadczysz mixinów.

Czy jednak mechanizmy dostępne w danym języku są tak bardzo istotne? Wg mnie bardziej liczy się to w jaki sposób są wykorzystywane, np. dziedziczenia można użyć tak samo źle w obydwu ;-)

1

W Javie 8 metody w interfejsach mogą mieć domyślne implementacje, a klasa (bądź interfejs) może implementować wiele interfejsów. Mamy więc wielodziedziczenie metod, ale kompilacja wysypuje się, gdy kompilator napotyka na diamond problem.

0

Python jest super! Jeżeli ktoś ma wątpliwości powinien zajrzeć tutaj: https://www.python.org/about/success/

1

Czyli cytat z tytułu wątku możemy uznać za obalony.

Edit: @Haskell: moim zamiarem nie było naganianie na pythona, ale cieszę sie, że tak wyszło:). Pewnie można by więcej, ale podam jeden przykład, w javie chyba nigdy nie pamietam jak otworzyć plik, a python: open(file_name) :)

0

Ale co z tym plikiem chcesz zrobić?

1

W Javie 1.7+ trzeba najpierw zajrzeć do klasy java.nio.files.Files i poszukać czy jakaś metoda zwraca to czego chcemy. Do otwierania plików mamy:

  • newBufferedReader (pliki tekstowe)
  • newBufferedWriter (pliki tekstowe)
  • newInputStream (pliki binarne)
  • newOutputStream (pliki binarne)
  • newByteChannel (do zapisu, odczytu, przesuwania wskaźnika, itd jednocześnie)
0
scibi92 napisał(a):

Ale co z tym plikiem chcesz zrobić?

https://docs.python.org/3/library/io.html

0

@lion137:
Najprostsze wczytywanie tekstu w Javie -> https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path- zwraca (leniwy) stream do lini,
żeby utworzyć binary strumien wystarczy zrobić:

InputStream inputStream = new FileInputStream(String pathToFile);
1

FileInputStream i FileOutputStream lepiej nie używać: FileInputStream / FileOutputStream Considered Harmful

0

OK, OK, wierzę, że w javie można wczytać plik do programu:). Ale do rzeczy, póki co wynika, że żaden z inkryminowanych języków nie jest "bardziej obiektowy", wypadało by, żeby jeszcze autor otwierającego wątek cytatu się wypowiedział.

0

Na 99% chodziło o to, że w Pythonie można zrobić 5.blabla(), a w Javce trzeba klepnąć blabla(5).

0

@lion137: mi chodziło o to że wiele osób uważa że w Javie trzeba się nie wiadomo jak rozpisać żeby coś osiągnąć, a to nie jest do końca prawdą ;)

0
Wibowit napisał(a):

Na 99% chodziło o to, że w Pythonie można zrobić 5.blabla(), a w Javce trzeba klepnąć blabla(5).

Chyba o to chodzi, że tu jest ta "flow" w obiektowości javy: nie wszystko jest obiektem na takich samych prawach, tzn. pewne typy (wbudowane )są traktowane inaczej. Chociaż interpreter Pythona3 nie pozwala mi stosować, w przeciwieństwie do Ruby, metod na integerze.

0

Te metody, które mogłyby być wywoływane na prymitywach znajdują się w klasie java.lang.Math. To nie jest jakoś specjalnie często wykorzystywana klasa w typowym biznesowym kodzie Javowym (czytaj: jest praktycznie nieużywana).

Brak metod na prymitywach sprawia tylko, że Javowe implementacje algorytmów poznawanych na pierwszym czy drugim roku studiów wyglądają bardzo podobnie do implementacji w C/ C++. W C# wyglądałyby nieco inaczej, ale i tak wielkiej różnicy by nie było.

0
Wibowit napisał(a):

Te metody, które mogłyby być wywoływane na prymitywach znajdują się w klasie java.lang.Math. To nie jest jakoś specjalnie często wykorzystywana klasa w typowym biznesowym kodzie Javowym (czytaj: jest praktycznie nieużywana).

Brak metod na prymitywach sprawia tylko, że Javowe implementacje algorytmów poznawanych na pierwszym czy drugim roku studiów wyglądają bardzo podobnie do implementacji w C/ C++. W C# wyglądałyby nieco inaczej, ale i tak wielkiej różnicy by nie było.

Yhy.
Java ma wrappery, jak Integer, które to obchodzą. Ale jednak, wychodzi na to, że python jest bardziej obiektowy; bo patrząc głębiej (a, nie tylko jak wywołać metodę na prymitywie), to w pythonie wszystko (prawie wszystko, for obiektem na przykład nie jest) jest obiektem - ma atrybuty, metody, a w javie tak nie jest, no właśnie co nie jest obiektem w javie, a jest w pythonie; i co to w ogóle jest object?

0

Java ma wrappery, jak Integer, które to obchodzą.

Metody z java.lang.Math i java.lang.Integer się nie pokrywają.

Ale jednak, wychodzi na to, że python jest bardziej obiektowy; bo patrząc głębiej (a, nie tylko jak wywołać metodę na prymitywie), to w pythonie wszystko (prawie wszystko, for obiektem na przykład nie jest) jest obiektem - ma atrybuty, metody, a w javie tak nie jest, no właśnie co nie jest obiektem w javie, a jest w pythonie; i co to w ogóle jest object?

Języki programowania to dość proste narzędzia i nie ma sensu dorabiać do nich jakichś daleko idących teorii.

Scala dla przykładu jest kompilowana do Javowego bajtkodu, więc szczegóły implementacyjne na tym poziomie ma w zasadzie te same (Scala nie wykorzystuje jakichś sztuczek z bajtkodem, których nie da się osiągnąć z Javy). Na poziomie kodu źródłowego są jednak znaczne różnice. Można wywoływać metody na incie, można też używać metod jak funkcji, czyli przekazywać wprost jako parametry funkcji:
https://www.ideone.com/QU1NoB

object Main extends App {
	println(5.hashCode())
	println(metoda2(metoda1))
 
	def metoda1(a: Int): Float =
		a * 1.5f
 
	def metoda2(funkcja: Int => Float) =
		funkcja(5)
}
0

No tak, to faktycznie, nie można napisać niczego innego w pythonie niż w C, bo "kanoniczny" python interpreter jest w C. Tak samo możemy napisać interpreter C w pythonie. W takim razie ojcem programowania jest Turing, on napisał pierwszy interpreter: Uniwersalna Maszynę Turinga.

1 użytkowników online, w tym zalogowanych: 0, gości: 1