Najważniejsza teoria w JAVA

0

Witam,
Jestem studentem i mam mały problem z programowaniem w java. Miałem ten przedmiot na studiach lecz nie udało mi się go zaliczyć w pierwszym terminie. Do poprawki zostało ok. miesiąca i chciałbym się do tego przyłożyć i zaliczyć ten przedmiot. Ze slajdów prowadzącego wypisałem moim zdaniem najważniejsze tematy jakie on poruszał na temat java :
Klasy abstrakcyjne/Interfejsy
Dziedziczenie
Klasa Object
Klonowanie
Kolekcje
Wyjątki
Aplety

I teraz mam pytanie do was drodzy użytkownicy :) Czy byłby ktoś w stanie zadawać w tym dziale pytania dotyczące każdego z tych działów tak aby zobaczyć czy jestem dobrze z tego przygotowany ? Na każdy z działów chciałbym sobie przeznaczyć 1-2 dni.

Z góry dziękuje za pomoc ! :)

0

Kompozycja vs dziedziczenie

2

Program który potrafi przyjąć funkcję liniową/kwadratową/wielomiad 3ciego stopa w formie y=3+2x+4x^2, sparsować, i obliczyć miejsca zerowe/maxima/minima?

0

Takie było ostatnio jedno z zadań.
Wykonanie programu wymaga użycia stosu, na którym zapisywane sa zmienne oraz ich wartości. Stan stosu zapisujemy jako ciąg list par
odpowiadający metodom na stosie i zmiennym zadeklarowanym i modyfikowanym w czasie ich wykonania.
Lista par odpowiada metodzie na stosie, jest zapisana w nawiasie kwadratowym, a każda para składa się z nazwy zmiennej oraz jej wartości
np: [..., (x,7),(y,true)]main to stan, w których wykonywana jest metoda main, a wartości zmiennych x i y sa odpowiednio równe 7 i true.
Rozważ następujący kod:

class A {
public static void m(int x){
...;//x
...;//y
 }
}
public static void main(String[] args)
{....;//A
.....;//B
.....;//C
.....;
.....;//D}}
0

Ciąg list par to by było coś takiego

[
  [(x:true),(x:true),(x:true),(x:true)],
  [(x:true),(x:true),(x:true),(x:true)],
  [(x:true),(x:true),(x:true),(x:true)],
  [(x:true),(x:true),(x:true),(x:true)],
  [(x:true),(x:true),(x:true),(x:true)],
  [(x:true),(x:true),(x:true),(x:true)]
]

co nie?

0

Dlaczego do tworzenia ogólnych klas/interfejsów/metod używamy kolekcji a nie referencji do klasy Object ? Jaki problem rozwiązują kolekcje ?

0

To zadanie jest bardzo zawiłe i nie za bardzo wiadomo o co w nim chodzi. Ja nie potrafię skminić o co chodzi i czego się ode mnie wymaga.

0

A czy ktoś byłby mi w stanie wytłumaczyć wyniki tego programu ? Niestety nie mam zdjęcia klasy F ;/
http://pokazywarka.pl/qamhk7/

1

Ten kod, wygląda jak g**no:

class F {
    public int n(int value) {
        return 0;
    }
}

public class G extends F {
static int t = 3;
int f = 13;

public int n(int x) {
    return (--f)*(++x + 2)+ --t;
}

public static void main(String[] args) {
    F o1 = new F();
    G o2 = new G();
    System.out.println("o2.f = " + o2.f);
    int x = 0;

    System.out.println("o1.n(x) = " + o1.n(x));
    System.out.println("o2.n(x) = " + o2.n(x));

    System.out.println("x = " + x);
    System.out.println("o2.f = " + o2.f);
    System.out.println("t = " + t);
    
    
    
}
}

Dużo lepiej wygląda ten

public class G extends F {
    static int t = 3;
    int f = 13;

    public int n(int x) {
        --f;
        --t;
        return f * (x + 3) + t;
    }

    public static void main(String[] args) {
        F f = new F();
        G g = new G();
        System.out.println("g.f = " + g.f);
        int x = 0;

        System.out.println("f.n(x) = " + f.n(x));
        System.out.println("g.n(x) = " + g.n(x));

        System.out.println("x = " + x);
        System.out.println("g.f = " + g.f);
        System.out.println("t = " + t);
    }
}

Ale niestety bez kodu tej klasy F, nie da się wywróżyć co tam się mogło dziać.

0

Witam, czy byłby ktoś w stanie wytłumaczyć jak praktycznie podejść do tego zadania ze zdjęcia ?
http://pokazywarka.pl/hx4boo/

0

Na początek włącz komputer, potem uruchom ulubione IDE (ewentualnie ulubiony edytor). Dalej to już będzie z górki.

public class TrippleOccurences extends Exception
{
    private String msg = "";
    public TrippleOccurences(int value)
    {
        msg = "Wartość " + value + " wystąpiła trzykrotnie";
    }
    public String toString()
    {
    	return "TrippleOccurences: " + msg;
    }
    public String getMessage()
    {
        return msg;
    }
}
import java.util.*;

public class IntegerList
{
    private Vector<Integer> list = new Vector<Integer>();
    public IntegerList(int size)
    {
        Random r = new Random();
        for(int i = 0;i<size;i++)
        {
            list.add(r.nextInt(10));
        }
    }
    public Vector<Integer> findDuplicates() throws TrippleOccurences
    {
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        //pętla po zmiennej list wypełniająca mapę parami (wartość, krotność)
        Vector<Integer> duplicates = new Vector<Integer>();
        for(int value:map.keySet())
        {
            int multiplicity = map.get(value);
            if(multiplicity > 2)
            {
                throw new TrippleOccurences(value);
            }
            else if(multiplicity == 2)
            {
                duplicates.add(value);
            }
        }
        return duplicates;
    }
}

Pominiętą pętlę i kod testujący to już napisz sam.

1

Czyżby prowadzący to legenda WATU, Pikej?

0

Czy umiałby ktoś wytłumaczyć mi dlaczego z poniższego kodu wynik to 15 ?

public class A 
{
	int a = 2;
	public int m(int x)
	{
		return a*(++x);
	}
}

public class B extends A
{
	int a = 3;
	
	public int m(int x)
	{
		return a*(++x);
	}
	public static void main(String[] args)
	{
		A o = new B();
		int x = 4;
		System.out.println(o.m(x));
	}
}
0

Bo 3 * 5 = 15.

0

Bo 35 = 15? Co to za pytanie? Interesuje cię tylko klasa B. Masz tam metodę m która robi a(++x) czyli a*(x+1) czyli 3*(x+1). A skoro za x podstawiasz 4 to masz 3*(4+1) = 15

0

Ja może zadam trochę konkretniej pytanie, ponieważ też nie do końca rozumiem dlaczego wybierana jest metoda z klasy B. W programie mamy tworzony obiekt typu A i referencję do tego obiektu jako o = new B();. Czy w takim wypadku przy wywołaniu o.m(); nie powinna być brana metoda z klasy A? Widząc jaki jest wynik widać, że odpowiedzią na moje pytanie jest "nie" :P, ale może ktoś byłby w stanie to jakoś jasno wyjaśnić, dlaczego wybierana jest metoda obiektu B, a nie metoda obiektu A skoro obiekt jest typu A?

0

Taki przykład: Załóżmy że masz nadklasę Pracownik, która ma metodę wypłaćPensję() i zwraca ona 1500. Masz też klasę Programista, który dziedziczy po klasie Pracownik, bo w końcu obiekt klasy Programista JEST również obiektem klasy Pracownik. No i w klasie Programista metoda wypłaćPensję() jest overridowana i zwraca 3500 zamiast 1500. Następnie przyjmujesz nowego pracownika i dajesz mu umowę o pracę dla pracownika, taką szablonową. Czyli zadeklarowałeś jako obiekt klasy Pracownik. ALE ten człowiek będzie na stanowisku programisty, wobec czego jest jednocześnie programistą i pracownikiem - Kadry wiedzą, że zatrudniły nowego PRACOWNIKA, który w rzeczywistości jest PROGRAMISTĄ. Wypłacając mu pensję, sprawdzasz, czy jego wyróżniony typ (Programista) ma swoją własną odmianę metody wypłaćPensję(). Jeśli tak, to tyle mu wypłacasz. Jeśli nie, to szukasz tej metody w nadklasie Pracownik.

0

Niby rozumiem, bo to co napisałeś ma sens, ale czym różni się to od zapisu B o = new B();? lub biorąc twój przykład, dlaczego nie zrobić Programista p = new Programista();, skoro i tak klasa Programista rozszerza klasę Pracownik? W jakich wypadkach jest konieczność robienia tego w taki sposób, że używa się A o = new B(); zamiast tego co napisałem wyżej.

Może mój problem polega właśnie na tym, że nie widzę sensu stosowania takiego zapisu :P?

0

A pomyśl teraz co jest elastyczniejsze - dla każdego nowego PRACOWNIKA dawać mu tę samą, generyczną umowę o pracę i tylko zmienić nazwę stanowiska i tam zakres obowiązków, CZY dla każdego stanowiska szykować osobne umowy? ;) Albo np opis jakiejś dużej firmy - piszą że pracuje w niej np 1000 pracowników. Nie piszą, że pracuje 200 programistów, 100 kierowników, 100 sekretarek i 600 ślusarzy.

Tak bardziej programistycznie - dobrą praktyką jest deklarować zawsze interfejsami (lub nadklasami). Chodzi o to, że jeśli na sztywno ustawisz obiekt typu B, to jakbyś potem chciał ten obiekt zmienić na klasę C (która też by dziedziczyła po A), to musiałbyś zapewne zmienić trochę w kodzie. A jeśli zostawiłbyś A a = new B(); to potem jedyna zmiana z klasy B na C byłaby taka: A a = new C();

1

@lukasz1988
To ja Ci napiszę ciut praktyczniej niż @Pinek.
Wyobraź sobie, że masz palącą potrzebę posiadania listy obiektów klasy typu A (niech będą to właśnie ci pracownicy). Lecimy dalej - chcesz mieć listę pracowników danej firmy więc tworzysz np. ArrayList, który potrafi trzymać obiekty typu A. Ale masz klase B i C, które również dziedziczą po A (więc są pracownikami - spawaczem czy tam koderem).

No i tutaj takie ArrayList przechowa wszystkie te obiekty. I jak będziesz chciał to możesz np. użyć foreach, żeby sobie tę listę przeiterować i nie robi tu różnicy jaka to klasa, byle by dziedziczyła po A (i były wołane metody z A).

0

No ale napisałem taki krótki kod:

package praca;

import java.util.ArrayList;

class Pracownik{
    String imie;
    String nazwisko;
    double zarobki;
    
    Pracownik(String imie, String nazwisko, double zarobki){
        this.imie = imie;
        this.nazwisko = nazwisko;
        this.zarobki = zarobki;
    }
    @Override
    public String toString(){
        return "Imię: " + imie + ", Nazwisko: " + nazwisko + ", Zarobki: " + zarobki;
    }
    
}

class Programista extends Pracownik{
    double premia;
    Programista(String imie, String nazwisko, double zarobki, double premia){
        super(imie, nazwisko, zarobki);
        this.premia = premia;
    }
    @Override
    public String toString(){
        return super.toString() + ", Premia: " + premia + "%";
    }
}

class Technolog extends Pracownik{
    double premia;
    Technolog(String imie, String nazwisko, double zarobki, double premia){
        super(imie, nazwisko, zarobki);
        this.premia = premia;
    }
    public String toString(){
        return super.toString() + ", Premia: " + premia + "%";
    }
}

public class Praca {

    public static void main(String[] args) {
        ArrayList<Pracownik> lista = new ArrayList<>();
        Pracownik p1 = new Pracownik("Lukasz", "Nowak", 2000);
        Programista p2 = new Programista("Krzysztof", "Zapałka", 2500, 0.25);
        Technolog p3 = new Technolog("Janusz", "Bąk", 2500, 0.2);
        lista.add(p1);
        lista.add(p2);
        lista.add(p3);
        for(Pracownik e: lista) System.out.println(e);
    }
}

I kompilator nie wyrzuca mi żadnego błędu, bez problemu mogę dodawać Pracownika, Programistę i Technologa do tablicy Pracowników i później zostaną oni prawidłowo wyświetleni.

Nawet jeżeli fragment kodu:

        Pracownik p1 = new Pracownik("Lukasz", "Nowak", 2000);
        Programista p2 = new Programista("Krzysztof", "Zapałka", 2500, 0.25);
        Technolog p3 = new Technolog("Janusz", "Bąk", 2500, 0.2);

zamienię na:

        Pracownik p1 = new Pracownik("Lukasz", "Nowak", 2000);
        Pracownik p2 = new Programista("Krzysztof", "Zapałka", 2500, 0.25);
        Pracownik p3 = new Technolog("Janusz", "Bąk", 2500, 0.2);

Program działa identycznie więc ciągle nie rozumiem dlaczego powinienem tworzyć obiekty tak jak napisałem przy drugim sposobie, a nie tak jak jest to w programie czy też w pierwszym fragmencie.

Może ktoś mógłby zmodyfikować mój program tak żeby było widać różnicę dla której warto definiować obiekty np:

        Pracownik p = new Programista();
0

@lukasz1988 to akurat dość proste. Napisz mi teraz funkcje która sortuje listę Pracowników po ich pensji. Przy czym twój kod jest bez sensu bo masz niby zdefiniowane dwie klasy, ale one są identyczne. Dodaj do programisty jeszcze np. przychód z przeniesienia prawa własności i dodaj metodę do Pracownika która zwraca roczne zarobki (i odpowiednio overriduj tą metodę w technologu i programiście).

0

Muszę przyznać, że trochę z lenistwa zrobiłem 2 klasy, które jedynie różnią się nazwą, a nie chciało mi się wymyślać pól unikalnych dla danej klasy ponieważ pomyślałem, że nie jest to tak istotne dla zrozumienia tematu :P.

Już prawię godzinę walczę z tym sortowaniem tablicy i coś mi nie idzie ;(, jak tylko nauczę się sortować to napiszę czy przykład coś mi rozjaśnił ^^.

Mógłbyś jeszcze wyjaśnić co miałeś na myśli pisząc "Dodaj do programisty jeszcze np. przychód z przeniesienia prawa własności", nie rozumiem tej części z przeniesieniem prawa własności.

EDIT:
Ok, coś takiego mi wyszło:

package praca;

import java.util.ArrayList;
import java.util.Collections;

class Pracownik implements Comparable<Pracownik>{
    String imie;
    String nazwisko;
    double zarobki;
    
    Pracownik(String imie, String nazwisko, double zarobki){
        this.imie = imie;
        this.nazwisko = nazwisko;
        this.zarobki = zarobki;
    }
    double roczneZarobki(){
        return this.zarobki * 12;
    }

    @Override
    public String toString(){
        return "Imię: " + imie + ", Nazwisko: " + nazwisko + ", Zarobki: " + zarobki;
    }

    @Override
    public int compareTo(Pracownik t) {
        if (zarobki == t.zarobki) return 0;
        else if (zarobki > t.zarobki) return 1;
        else return -1;
    }
}

class Programista extends Pracownik{
    double premia;
    String specjalizacja;
    Programista(String imie, String nazwisko, double zarobki, double premia, String specjalizacja){
        super(imie, nazwisko, zarobki);
        this.premia = premia;
        this.specjalizacja = specjalizacja;
    }
    
    @Override
    double roczneZarobki(){
        return this.zarobki * premia * 12;
    }
    @Override
    public String toString(){
        return super.toString() + ", Premia: " + premia + "%, Specjalizacja: " + specjalizacja;
    }
}

class Technolog extends Pracownik{
    double premia;
    Technolog(String imie, String nazwisko, double zarobki, double premia){
        super(imie, nazwisko, zarobki);
        this.premia = premia;
    }
    
    @Override
    double roczneZarobki(){
        return this.zarobki * premia * 12;
    }
    @Override
    public String toString(){
        return super.toString() + ", Premia: " + premia + "%";
    }
}

public class Praca {

    public static void main(String[] args) {
        ArrayList<Pracownik> lista = new ArrayList<Pracownik>();
        
        Pracownik p1 = new Pracownik("Lukasz", "Nowak", 2400);
        Programista p2 = new Programista("Krzysztof", "Zapałka", 2200, 0.25, "Java");
        Technolog p3 = new Technolog("Janusz", "Bąk", 2500, 0.2);
        
        lista.add(p1);
        lista.add(p2);
        lista.add(p3);
        
        for(Pracownik e: lista) System.out.println(e);
        
        Collections.sort(lista);
        
        System.out.println("\nPosortowana według zarobków:\n");
        
        for(Pracownik e: lista) System.out.println(e);
    }
}

Nadal wszystko działa, bez względu na to czy wszystkie obiekty definiuję jako klasę "Pracownik", czy każdy jest oddzielnie Pracownikiem, Programistą, Technologiem. W obu przypadkach sortowanie działa tak samo i bez problemów.

Bardzo chciałbym to zrozumieć, bo już wcześniej z tym się spotykałem ale coś chyba za tępy jestem żeby to ogarnąć, a pewnie jak już kiedyś zrozumiem to będę się zastanawiał czego tu można było nie rozumieć xd.

0

Ale teraz twoje sortowanie jest bez sensu bo uwzględnia tylko zarobki a permii już nie. Poza tym nie masz racji, bo zauważ że sortujesz już kolekcje obiektów Pracownik, bez rozróżnienia na to jaki to "typ" pracownika. Co wiecej, jakbym dodał teraz nową klasę rozszerzającą Pracownika to nadal kod który operuje na Pracowniku mógły z obiektami tej klasy działać, nawet pomimo faktu że ten kod został napisany zanim w ogóle tą swoją klasę wymyśliłem.

0

Ale teraz twoje sortowanie jest bez sensu bo uwzględnia tylko zarobki a permii już nie.

To prawda, dopiero jak zwróciłeś na to uwagę to sam to zauważyłem ^^. Jak by ktoś zaglądał do tamtego kodu to należy tam wstawić metody zwracające zarobki pomnożone o premię oraz w metodzie compareTo zamienić porównanie pól na porównanie wartości zwracanych przez metody zwracające zarobki.

Poza tym nie masz racji, bo zauważ że sortujesz już kolekcje obiektów Pracownik, bez rozróżnienia na to jaki to "typ" pracownika. Co wiecej, jakbym dodał teraz nową klasę rozszerzającą Pracownika to nadal kod który operuje na Pracowniku mógły z obiektami tej klasy działać, nawet pomimo faktu że ten kod został napisany zanim w ogóle tą swoją klasę wymyśliłem.

To też niby rozumiem, ale i tak nie wiem dlaczego miało by być zasadne pisanie:

Pracownik p1 = new Programista();

zamiast:

Programista p1 = new Programista();

Skoro w przypadku obu definicji wszystko mi działa tak samo (przynajmniej w przypadku mojego programu).

No ale nic to, pewnie jeszcze za mało umiem, muszę jeszcze się trochę pouczyć i minie trochę czasu zanim mi się to w głowie poukłada.

Dzięki za cierpliwość i odpowiedzi :]

0

@lukasz1988 bo używając typu Programista uzależniasz kod od tego konkretnego typu i w trakcie pisania kodu nie będziesz myślał juz czy jakaś metoda pochodzi z Pracownika czy z Programisty. Jeśli użyjesz typu bazowego, albo lepiej: interfejsu, to będziesz od razu widział kiedy "brakuje" co jakiejś metody która powinna być "wspólna". Niemniej oczywiście nie zawsze takie działanie ma sens - czasem chcesz mieć dostęp do tego konkretnego podtypu. Wszystko w granicach zdrowego rozsądku.

0

Dziękuje wszystkim za wszystkie porady :) Na prawdę mi dużo pomogły ! Czy ma ktoś może jakis pomysł na projekt w którym mógłbym wykorzystać wszystkie te działy, które wcześniej napisałem ? Sam nie mam pomysłu a chciałbym to poćwiczyć i zaliczyć przedmiot we wrześniu :)

0

A te aplety koniecznie? ;] Napisz aplet do grania w karty.

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