Hi! Dina iki kita bakal nliti mekanisme penting: warisan ing kelas nested. Apa sampeyan tau mikir babagan apa sing bakal ditindakake yen sampeyan kudu nggawe kelas sing bersarang dadi warisan kelas liyane. Yen ora, pracaya kula: kahanan iki bisa mbingungake, amarga ana akeh nuansa.
Aturan warisan sing paling gampang. Ing kene sampeyan bisa nindakake meh kabeh sing dikarepake. Kelas bersarang statis bisa diwenehi warisan:
Maneh, ayo pindhah saka prasaja menyang kompleks :)
- Apa kita nggawe kelas nested warisan sawetara kelas? Utawa kita nggawe sawetara kelas warisan kelas nested?
- Apa anak / wong tuwa kelas kelas umum biasa, utawa uga kelas nested?
- Pungkasan, apa jinis kelas nested sing digunakake ing kabeh kahanan kasebut?
Kelas nested statis

- kelas biasa
- kelas nested statis sing diumumake ing kelas njaba utawa leluhure
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Ayo nyoba ngganti kode lan nggawe Drawing
kelas nested statis lan turunane - Boeing737Drawing
.
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
public static class Boeing737Drawing extends Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Nalika sampeyan bisa ndeleng, ora masalah. Kita malah bisa narik metu Drawing
kelas lan nggawe kelas umum biasa tinimbang kelas nested statis - ora bakal ngganti.
public class Drawing {
}
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Boeing737Drawing extends Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Kita ngerti iki. Nanging kelas apa sing bisa marisi kelas nested statis? Praktis wae! Nested/non-nested, statis/non-statis — ora masalah. Ing kene kita nggawe Boeing737Drawing
kelas njero marisi Drawing
kelas nested statis:
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
public class Boeing737Drawing extends Drawing {
public int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Sampeyan bisa nggawe conto Boeing737Drawing
kaya iki:
public class Main {
public static void main(String[] args) {
Boeing737 boeing737 = new Boeing737(1990);
Boeing737.Boeing737Drawing drawing = boeing737.new Boeing737Drawing();
System.out.println(drawing.getMaxPassengersCount());
}
}
Senajan Boeing737Drawing
kelas kita marisi kelas statis, iku ora statis dhewe! Akibaté, mesthi mbutuhake conto saka kelas njaba. Kita bisa mbusak Boeing737Drawing
kelas saka Boeing737
kelas lan nggawe kelas umum prasaja. Ora ana owah-owahan. Iku isih bisa oleh warisan Drawing
kelas nested statis.
public class Boeing737 {
private int manufactureYear;
public static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
}
public class Boeing737Drawing extends Boeing737.Drawing {
public int getMaxPassengersCount() {
return Boeing737.maxPassengersCount;
}
Siji-sijine titik penting yaiku yen ing kasus iki kita kudu nggawe maxPassengersCount
publik variabel statis. Yen tetep pribadi, kelas umum biasa ora bakal bisa ngakses. Kita wis ngerti kelas statis! :) Saiki ayo pindhah menyang kelas batin. Ana 3 jinis: kelas batin sing sederhana, kelas lokal, lan kelas njero anonim. 
Kelas batin anonim
Kelas batin anonim ora bisa marisi kelas liyane. Ora ana kelas liyane sing bisa marisi kelas anonim. Iku ora bisa dadi luwih prasaja! :)Kelas lokal
Kelas lokal (yen sampeyan kelalen) diumumake ing blok kode kelas liyane. Paling asring, iki kedadeyan ing sawetara metode kelas njaba. Secara logis, mung kelas lokal liyane ing metode sing padha (utawa blok kode) sing bisa entuk warisan kelas lokal. Punika conto:
public class PhoneNumberValidator {
public void validatePhoneNumber(final String number) {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber() {
this.phoneNumber = number;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
class CellPhoneNumber extends PhoneNumber {
}
class LandlinePhoneNumber extends PhoneNumber {
}
// ...number validation code
}
}
Iki kode saka pawulangan kita ing kelas lokal. Kelas validator nomer kita duwe PhoneNumber
kelas lokal. Yen kita butuh kanggo makili rong entitas sing béda, contone, nomer ponsel lan nomer telpon darat, kita mung bisa nindakake iki ing cara sing padha. Alesané prasaja: ruang lingkup kelas lokal diwatesi karo metode (blok kode) sing diumumake. Akibaté, kita ora bakal bisa nggunakake externally (kalebu kanggo warisan kelas). Nanging, kemungkinan warisan ing kelas lokal dhewe luwih akeh! Kelas lokal bisa diwenehi warisan:
- Kelas biasa.
- Kelas batin sing diumumake ing kelas sing padha karo kelas lokal utawa ing salah sawijining leluhur.
- Kelas lokal liyane diumumake kanthi cara sing padha (blok kode).
public class PhoneNumberValidator {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
public void validatePhoneNumber(final String number) {
class CellPhoneNumber extends PhoneNumber {
public CellPhoneNumber(String phoneNumber) {
super(number);
}
}
class LandlinePhoneNumber extends PhoneNumber {
public LandlinePhoneNumber(String phoneNumber) {
super(number);
}
}
// ...number validation code
}
}
Ing kene kita mbusak PhoneNumber
kelas saka validatePhoneNumber()
metode kasebut lan nggawe kelas njero tinimbang kelas lokal. Iki ora ngalangi kita nggawe 2 kelas lokal dadi warisan. Tuladha 2 — "... utawa ing leluhur kelas iki." Saiki iki wis luwih menarik. Kita bisa pindhah PhoneNumber
luwih dhuwur ing rantai pusaka. Ayo ngumumake AbstractPhoneNumberValidator
kelas abstrak, sing bakal dadi leluhur PhoneNumberValidator
kelas kita:
public abstract class AbstractPhoneNumberValidator {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
}
Kaya sing sampeyan ngerteni, kita ora mung ngumumake - kita uga mindhah PhoneNumber
kelas njero. Nanging, ing turunane PhoneNumberValidator
, kelas lokal sing diumumake kanthi metode bisa entuk warisan PhoneNumber
tanpa masalah!
public class PhoneNumberValidator extends AbstractPhoneNumberValidator {
public void validatePhoneNumber(final String number) {
class CellPhoneNumber extends PhoneNumber {
public CellPhoneNumber(String phoneNumber) {
super(number);
}
}
class LandlinePhoneNumber extends PhoneNumber {
public LandlinePhoneNumber(String phoneNumber) {
super(number);
}
}
// ...number validation code
}
}
Amarga hubungan warisan, kelas lokal ing kelas turunan "ndeleng" kelas batin ing leluhur. Lan pungkasane, ayo nerusake menyang grup pungkasan :)
Kelas batin
Kelas batin sing diumumake ing kelas njaba sing padha (utawa ing turunane) bisa marisi kelas batin liyane. Ayo njelajah iki nggunakake conto kita karo sepeda saka pawulangan ing kelas batin.
public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
public void start() {
System.out.println("Let's go!");
}
class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
class SportSeat extends Seat {
// ...methods
}
}
Ing kene kita ngumumake Seat
kelas batin ing njero Bicycle
kelas. A jinis khusus saka jog racing, SportSeat
, warisan iku. Nanging, kita bisa nggawe jinis "sepeda balap" sing kapisah lan dilebokake ing kelas sing kapisah:
public class SportBicycle extends Bicycle {
public SportBicycle(String model, int maxWeight) {
super(model, maxWeight);
}
class SportSeat extends Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
}
Iki uga pilihan. Golongan batin turunan ( SportBicycle.SportSeat
) “ndeleng” golongan batine leluhur lan bisa oleh warisan. Warisan kelas batin nduweni fitur sing penting banget! Ing rong conto sadurunge, SportSeat
kelas kita minangka kelas batin. Nanging kepiye yen kita mutusake nggawe SportSeat
kelas umum biasa sing uga entuk warisan Seat
kelas batin?
// Error! No enclosing instance of type 'Bicycle' is in scope
class SportSeat extends Bicycle.Seat {
public SportSeat() {
}
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
Kita entuk kesalahan! Sampeyan bisa guess apa? :) Iku kabeh langsung. Nalika kita ngomong babagan Bicycle.Seat
kelas njero, kita kasebut yen referensi kanggo conto saka kelas njaba sacara implisit liwati menyang konstruktor kelas njero. Iki tegese sampeyan ora bisa nggawe Seat
obyek tanpa nggawe Bicycle
obyek. Nanging apa bab nggawe a SportSeat
? Boten kados Seat
, iku ora duwe mekanisme dibangun ing iki kanggo implicitly maringaken konstruktor referensi kanggo Kayata saka kelas njaba. S nganti, tanpa Bicycle
obyek, kita ora bisa nggawe SportSeat
obyek, kaya ing kasus Seat
. Mulane, mung ana siji bab sing kudu ditindakake - kanthi jelas ngirim SportSeat
referensi menyang konstruktor menyang Bicycle
obyek. Mangkene carane nindakake:
class SportSeat extends Bicycle.Seat {
public SportSeat(Bicycle bicycle) {
bicycle.super();
}
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
Kita nelpon konstruktor superclass nggunakake super();
Saiki, yen kita pengin nggawe SportSeat
obyek, ora ana sing bakal nyegah kita nindakake iki:
public class Main {
public static void main(String[] args) {
Bicycle bicycle = new Bicycle("Peugeot", 120);
SportSeat peugeotSportSeat = new SportSeat(bicycle);
}
}
Phew! Pawulangan iki rada suwe :) Nanging sampeyan sinau akeh! Saiki wektune kanggo ngrampungake sawetara tugas! :)
GO TO FULL VERSION