» »

[Java] Konstruktorji

[Java] Konstruktorji

shadeX ::

Lepo pozdravljeni.

Učim se javo in mi gre kar dobro. Sicer sem naletel na eno težavico zato vas prosim, če mi obrazložite, zakaj sploh uporabljamo konstruktorje oz. metode konstruktorja. Sam vem definicijo. Recimo dam primer.


public Bicycle(int startCadence, int startSpeed, int startGear) {
    gear = startGear;
    cadence = startCadence;
    speed = startSpeed;
}


Konstruktor je pač kot nek načrt za izdelavo objekta. Sedaj če naredim objekt na ta konstruktor.

Bicycle gorskoKolo = new Bicycle(1, 5, 1) <- Argumenti, ki jih Bicycle konstruktor zahteva


Samo vedno ko sem gledal tutoriale in vse možne vodiče so recimo argumenti ki jih zahteva metoda v konstruktorju enaki spremenljivkam v razredu. Nevem če sem se pravilno izrazil vendar poglejte to.

 gear = startGear;
    cadence = startCadence;
    speed = startSpeed;


To so spremenljivke iz razreda, ki se enačijo z argumenti v metodi. Mislim tukaj so moji možgani totalno zmešani.. :D

Dajte mi kak zahteven primer konstruktorja še in če kdo pozna kako dobro razlago za konstruktor. Ker sam če grem sedaj programirat NE VEM kdaj uporabit konstruktor. Malo me še mede.. :S
  • spremenil: shadeX ()

shadeX ::

Na offical java strani mi piše lepo:
You don't have to provide any constructors for your class

Zakaj so potem konstruktorji, če mi jih ni potrebno definirat? A so mogoče samo zato da "na hitro" vstavimo nov objekt brez pisanja novih vrstic? a je samo to? ker to je edina prednost konstrukorja ki sem jo opazil do sedaj...

IceBoX ::

Hitreje gre pa manj vrstic. Če bi hotel ustvariti recimo nov objekt Uporabnik z atributi ime, priimek in starost.

Brez konstruktorjev:

Uporabnik u = new Uporabnik();
u.setIme("test");
u.setPriimek("testpriimek");
u.setStarost(18);

S konstruktorjem:

Uporabnik u = new Uporabnik("test", "testpriimek",18);
Huh...

abyssus ::

Z konstruktorjem ustvariš objekt ter z njim prirediš vrednosti podatkom v razredu.
Ne rabiš ga zato, ker prevajalnik privzeti konstruktor ustvari sam.

shadeX ::

Ola ola , hvala obema ;DD

KaRkY ::

Konstruktor se uporablja za tiste podatke ki so nujni recimo:
public class Person{
  private final String name;
  private Integer age;

  public Person(final String name){
    this name = name;
  }

  public String getName(){
    return name;
  }

  public void setAge(final Integer age){
    this.age = age;
  }

  public Integer getAge(){
    return age;
  }
}


V tem primeru je name obvezno in brez njega objekt nemore obstajati.
When you look long into an abyss, the abyss looks into you

shadeX ::

Aha. Tukaj si uporabil tako imenovane "getters in setters" :D Tudi to me zanima in sicer a po vsakem set, mora biti tudi return ? (get)

abyssus ::

V razred si spremenljivke ponavadi rezerviramo kot "private" kar pomeni, da direktno do njih ne moramo dostopati. Zato imamo metode "set" in "get". Set metoda spremenljivki nastavi vrednost, get metoda jo vrača. Ne rabiš imet obojega ampak tisto, kar pač rabiš. Če boš podatek samo bral, potem si narediš get metodo, če boš ga zapisoval pa set metodo.

kow ::

Zelo na kratko... poanta je, da ni nujno, da sta programer 'uporabnik' in programer 'knjižnice' ista oseba. Nasprotno, skoraj nikoli nista. Zato je pomembno, da modificiranje uporabniške kode ali modificiranje knjižnice ne poruši programa (skupek knjižnic). Zato se programerju uporabniku, omejeju dostop do notranjih stanj knjižnice => set in get methode...

shadeX ::

Aha aha razumem :D Kako je lepo k ti nekdo pove brez nekega kompliciranja. Hvala fanta =)

shadeX ::

Ok sedaj sem naredil eno set/get metodo. A je to vredu?

public class Person {
	
	private String name;
	
	void setPerson(String n){
		this.name = n;
		
	}
	
	String getPerson() {
		
	return name;
		
	}

}


To je pa Main Class

public class Main {

	
	
	public static void main(String[] args) {
		Person oseba1 = new Person();
		oseba1.setPerson("Rok");
		System.out.println(oseba1.getPerson());
		
		
	}

}


Se pravi če povzamem. To je enostavna set/get metoda, ki se uporablja za to da dostopamo do instanc razreda ki so določene kot "private" ? =) Če sem pravilno razumel ;D

b00mer ::

Ti s pomocjo get/set metod dostopas do private atributov(ki so v tem primeru private in skriti) vsakega objekta. Do objektov imas direktni dostop, ker je razred definiran kot public.

Probi se protected:
V razredu si nastavi atribute protected -> ne potrebujes set/get za razrede v istem paketu. Se pravi dostopas direktno Person.name ="Lolek";

shadeX ::

Imam eno vprašanje na katerega nisem dobil čistega odgovora še.

Recimo da imam 2 razreda. Prvi razred z imenom CarRental ter drugi razred je LuxuryCarRental, ki je v dedovanem razmerju z CarRental razredom.

CarRental razred zgleda nekako takole.

	String renterName;
	int zipCode;
	String sizeOfCar;
	double dailyRentalFee;
	int daysRented;
	double totalCost;
	
	public CarRental(String renterName, int zip, String carSize, int daysRented) {
		
		if(carSize.equals("economy")) {
			
			dailyRentalFee = 29.99;
		} else if(carSize.equals("midsize")) {
			
			dailyRentalFee = 38.99;
			
		} else if(carSize.equals("fullsize")) {
			
			dailyRentalFee = 43.50;
			
		}
		
		this.renterName = renterName;
		this.zipCode = zip;
		this.daysRented = daysRented;
		
		
	}
	


Ta razred ima polja ter konstruktor, ki določi "dailyRentalFee" za avto, kateri je odvisen od razreda ( ekonomski razred, srednji razred ali polni razred. Večji razred kakor je, večja je cena za najem avtomobila - dnevna cena ). No vse lepo in prav. Sedaj pa imam drugi dedovan razred LuxuryCarRental, ki skrbi da je dnevnica FIKSNA in sicer 79.99$. To pa zato ker je to luksuzni razred zato stane tudi več.

Ker je ta razred dedovan in ker vsebuje starš tega razreda konstruktor, to pomeni da moram konstruktor klicati tudi iz dedovanega razreda. Tukaj pa nastopi težava, ker parametrov za "carSize" oziroma izbiro paketa ( ki ga imam v starševskem razredu ), jaz ne potrebujem v dedovanem razredu ker je itak cena fiksna. Argument pa še vedno moram vnesti v dedovanem razredu v kodo super. Zanima me ali je vredu če tja vpišem argument "NULL" ?

public LuxuryCarRental(String renterName,  int zip, int daysRented) {
		super(renterName, zip, KATERI PARAMETER TUKAJ? NULL OK ?, daysRented);
		
		dailyRentalFee = 79.99;
		
		
	}




Upam da ste me razumeli kaj želim povedati..

KaRkY ::

Null definitivno nebi vredu ker ti bo v CarRental konstruktorju na vrstici 10 vrglo NullPointerException. Zakaj pa nemoreš dodati tega v CarRental? Jaz bi kot prvo se rešil carSize Stringa pa ga nadomestil z ENUM ali pa celo odstranil carSize in kot parameter podal dailyRentalFee.
When you look long into an abyss, the abyss looks into you

shadeX ::

Tako zahteva naloga od mene. Kot parameter konstruktorja morajo biti vsa polja razen totalcost in dailyrentafee, ker sta odvisna od paketa ki jih izbereš ( economy, midsize, fullsize ).

Zakaj pa nemoreš dodati tega v CarRental?


Zato ker v razredu ne izbiram več koliko je dnevni najem zato ker ga imam že fiksnega ( 79.99 ), tako da kadar se pač naredi nov LuxuryCarRental objekt , kupec nima več izbire kaj bo. Cena je fiksna. V CarRental pa lahko izbira..

Spura ::

class CarRental {
	protected String renterName;
	protected int zip;
	protected CarSize carSize;
	protected int daysRented;
	public CarRental(String renterName, int zip, CarSize carSize, int daysRented) {
		this.renterName = renterName;
		this.zip = zip;
		this.carSize = carSize;
		this.daysRented = daysRented;
	}
	
	public double getDailyRentalFee() {
		return carSize.getPrice();
	}

	public static enum CarSize {
		economy(29.99),
		midsize(38.99),
		fullsize(43.50);
		private double price;
		private CarSize(double price) {
			this.price = price;
		}
		protected double getPrice() {
			return price;
		}
	}
}

class LuxuryCarRental extends CarRental {
	public LuxuryCarRental(String renterName, int zip, int daysRented) {
		super(renterName,zip,null,daysRented);
	}
	public double getDailyRentalFee() {
		return 79.99;
	}
}
Tkole je karky mislu./

shadeX ::

aha ja tako bi šlo.
Vendar zanima me če obstaja še kakšna druga varianta ( brez enumov ), da bi rešil to nalogo?
Kako se rešuje primere ko superclass konstruktor potrebuje nekatere argumente, vendar jih v subclass konstruktorju ti nimaš? To me sedaj predvsem zanima..

Spura ::

Ce jih nimas je narobe, razen ce jih nimas zato ker jih ne rabis.
Poleg tega moja resitev nima veze z rabo enuma. Lahko bi napisal brez rabe enuma, pa bi bilo vse isto.
Fora je v tem, da racunam daily rental fee v getterju namesto v konstruktorju, in getter lepo overridam.
V osnovnem primeru se dailyRentalFee racuna takoj v konstruktorju cisto nepotrebno, in to na relativno zoprn nacin. Kar pomeni, da je snovalec razreda zajebal, ker ni predvidel tega scenarija.

shadeX ::

Hvala za odgovor. Si mi dal malo mislit..

Marat ::

sej lahko maš tudi več konstruktorjev v posameznem classu

alexa-lol ::

konstruktor je samo posebna kombinacija setter metod... dejansko se vse lahko naredi brez njih, so pa priročni.

darkkk ::

Tko no:
lej, ne rabiš razredov, metod, itd. Saj lahko vse v C-ju napišeš... sam ideja je, da do neke mere olajšaš in poenostaviš delo z objektnim programiranjem.

Je pa res, da so predstavitve OOPja dostikrat "preveč enostavne" v smislu, da se sprašuješ kje je dodana vrednost OOPja.

Spura ::

Poleg tega sploh ni res, da se vse da brez konstruktorjev narest, in da je to posebna kombinacija setter metod.

darkkk ::

Morda se v Javi ne da kake stvari narest brez konstruktorjev, ampak na splošno "konstruktorji" oz OOP ni potreben - je pa prekleto koristen. (Tole je precej filozofsko-teoretičen vidik, ne čist resno jemat, ampak Turingov stroj nima konstruktorja).

Randomness ::

Kdo ali kaj pa je potem Alan? >:D Alan, Alan, who ...

Zgodovina sprememb…

Spura ::

darkkk je izjavil:

Morda se v Javi ne da kake stvari narest brez konstruktorjev, ampak na splošno "konstruktorji" oz OOP ni potreben - je pa prekleto koristen. (Tole je precej filozofsko-teoretičen vidik, ne čist resno jemat, ampak Turingov stroj nima konstruktorja).

Ne pravim da se stvari ne da implementirat s stalisca izvajanja, ampak da se dolocenih stvari ne da compile-time enforceat.
Torej ti ne mores s setterji naredit razreda, ki je immutable v smislu sintakse. Konstruktor je metoda, ki se klice enkrat na objekt. Setter lahko klicem kolikokrat hocem. Lahko sicer notr dam kodo, ki mece exceptione po prvem klicu, ampak to ni isto s stalica pisanja kode.

Zgodovina sprememb…

  • spremenil: Spura ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

android črta

Oddelek: Programiranje
412366 (1637) g333kk
»

Java pomoč / Runnable problemi

Oddelek: Programiranje
7801 (666) Serial
»

c# base class, derived class, inheritance problem

Oddelek: Programiranje
91371 (1250) Vapo1
»

[JAVA] zaustavitev niti (threadov)

Oddelek: Programiranje
223116 (3116) morbo
»

[NALOGA][Java] Težave pri pisanju slikarja

Oddelek: Programiranje
202240 (1882) l0g1t3ch

Več podobnih tem