9. előadás (e-Kozsik 2.)
Altípus
- ExactTime mindent tud, amit a Time
- Amit lehet Time-mal, lehet ExactTime-mal is
- ExactTime \(<:\) Time (ExactTime altípusa Time-nak)
- \(\forall T\) osztályra: \(T <:\)
Java.lang.Object- A Javában minden osztály leszármazottja a
java.lang.Objectosztálynak
- A Javában minden osztály leszármazottja a
public class Time {
// ...
public void aMinutePassed(){ ... }
public boolean sameHourAs( Time that ){ ... }
}
public class ExactTime extends Time {
// ...
public boolean isEarlierThan( ExactTime that ){ ... }
}
ExactTime time = new ExactTime(); // 0:00:00
// Ezek a függvények léteznek, hiszen `ExactTime <: Time`
time.aMinutePassed(); // 0:01:00
time.sameHourAs( new ExactTime() ) // true
Liskov-féle helyettesítési elv (LSP) (Liskov's substitution principle)
Egy A típus altípusa a B (bázis-)típusnak \(\iff\) az A egyedeit használhatjuk a B egyedei helyett, anélkül, hogy ebből baj lenne.
Felkonvertálás
"Azért polimorf valami, mert típussal lehet paraméterezni"
-Kozsik
Statikus típus
A változó vagy paraméter deklarált típusa
- Programszövegből következik
- A fordító ez alapján típusellenőriz (fordítás időben)
- Megmondja, hogy mit lehet csinálni a változóval
Dinamikus típus
Futási időben derül ki
Van típusrendszer lmao
Túlterhelés
- Ugyanazzal a névvel, különböző szignatúrával
- Örökölt és bevezetett műveletek
- Fordítási időben dől el a szignatúra szerint
Felüldefiniálás (override)
- Bázisosztályban adott műveletre
- Ugyanazzal a névvel és paraméterezéssel
- Ugyanaz a metódus
- Egy példánymetódusnak lehet több implementációja
- Futás közben választódik ki a "legspeciálisabb" implementáció
Dinamikus kötés
ExactTime e = new ExactTime();
Time t = e;
Object o = t;
System.out.println( e.toString() ); // 0:00:00
System.out.println( t.toString() ); // 0:00:00
System.out.println( o.toString() ); // 0:00:00
A legjobban illeszkedő implementáció kerül meghívásra
Statikus típusellenőrzés
Dinamikus típusellenőrzés
Object o = new Time();
System.out.println(o.toString()); // Object-nek van toString típusa, ezért a Time által definiált toString metódust hívja le
Példa öröklődésre
package company.hr;
import java.time.ZonedDateTime;
import static java.time.temporal.ChronoUnit.YEARS;
public class Employee {
private ZonedDateTime startDate;
public int yearsInService(){
return (int) startDate.until(ZonedDateTime.now(), YEARS);
}
private static int bonusPerYearInService = 1;
public int bonus(){
return yearsInService() * bonusPerYearInService;
}
}
package company.hr;
import java.util.*;
public class Manager extends Employee {
// megörökölt: startDate, yearsInService(), bonus, stb.
private final HashSet<Employee> underlings = new HashSet<>();
public void addUnderling( Employee underling ){
underlings.add(underling);
}
private static int bonusPerUnderling = 1;
@Override public int bonus(){
return underlings.size() * bonusPerUnderling + super.bonus();
}
}
Employee[] company = {new Employee("Jack", 1000), new Manager("Eve", 1200)};
for( Employee e: company ){
totalSalaryCosts += e.salary(); // Az altípusnak megfelelő `salary` metódust hívja le
}
Mező és osztályszintű metódus nem definiálható felül
Például:
class Base {
int field = 3;
int iMethod(){ return field; }
static int sMethod(){ return 3; }
}
class Sub extends Base {
int field = 33; // elfedés, nem felüldefiniálás
static int sMethod(){ return 33; } // same
}
Amiért nem felüldefiniálás, ezért:
Sub sub = new Sub();
Base base = sub;
System.out.println(sub.field); //33
System.out.println(base.field); //3
// A Sub típusban lévő `field` az egy **teljesen más** mező, mint amit a Base-ben definiáltunk.
Konverziók referenciatípuson
Implicit konverzió
Upcast
Automatikus, altípusosság
Explicit konverzió
Downcast
Castolás (type-cast operator)
Object obj = new Time(3, 20);
obj.aMinutePassed(); //Fordítási hiba, Object-nek nincs aMinutePassed metódusa
((Time)obj).aMinutePassed(); //Lefordul!
Object o = "Ez egy String. Ez egy String! Ez egy Striiiiing.";
o.aMinutePassed(); // Triviális fordítási hiba
((Time)o).aMinutePassed(); // Nincs fordítási hiba, de futási lesz... Köztudottan a String, az nem egy Time
instanceof
Futási időben ellenőrizhető a változó típusa/altípusa
null esetén false
Típuskonverziók
Automatikus
byte < short < int < long long < float float < double char < int