• Tidak ada hasil yang ditemukan

INHERITANCE. Pelatihan Java 2 Mei 2015 Fakultas Teknologi Informasi Program Studi Teknik Informatika

N/A
N/A
Protected

Academic year: 2021

Membagikan "INHERITANCE. Pelatihan Java 2 Mei 2015 Fakultas Teknologi Informasi Program Studi Teknik Informatika"

Copied!
58
0
0

Teks penuh

(1)

Pelatihan Java – 2 Mei 2015

Fakultas Teknologi Informasi

Program Studi Teknik Informatika

Herika Hayurani – [email protected],

Nova Eka Diana – [email protected],

Nurmaya – [email protected],

(2)

Topics

• Hirarki Pewarisan

• Overriding Methods

• Constructor Subclass

• Konversi antar Tipe Subclass dan

Superclass

• Polimorfisme dan Pewarisan

• Access Specifier protected

(3)

Hirarki

Pewarisan (1)

• Kategorisasi konsep pewarisan dengan

menggunakan struktur hirarki

Algoritma & Pemrograman 2 -

(4)

Hirarki

Pewarisan (2)

• Himpunan class-class dapat membentuk

sebuah hirarki pewarisan

– Class-class merepresentasikan konsep paling

umum yang mendekati root, konsep lebih

khususnya mendekati cabang

• Superclass: class yang

lebih umum

• Subclass: class yang lebih

khusus dari superclassnya

– Contoh:

JPanel

adalah subclass dari

JComponent

(5)

Hirarki

Pewarisan:

Contoh (1)

• Contoh: tipe account yang berbeda:

1. Rekening Cek (CheckingAccount):

• Tidak ada bunga (interest)

• Sedikit transaksi per bulan

• Kenakan biaya transaksi untuk transaksi tambahan

2. Rekening Tabungan (SavingsAccount):

• Hasilkan bunga bulanan

.

Superclass: BankAccount

.

Subclasses: CheckingAccount & SavingsAccount

Algoritma & Pemrograman 2 -

(6)

Hirarki

Pewarisan:

Contoh (2)

• Behavior/perlakuan dari class rekening

(BankAccount, CheckingAccount,

SavingsAccount):

• Semua class mendukung method getBalance.

• Semua class mendukung method deposit dan withdraw, tetapi

detil implementasi berbeda.

• CheckingAccount perlu sebuah

method deductFees untuk

menghitung biaya bulanan dan

me-reset counter transaksi.

• CheckingAccount harus

meng-override method deposit

dan withdraw untuk menghitung

jumlah transaksi.

(7)

Latihan

Mengapa kita tidak menempat

kan method

addInterest di dalam class BankAccount

?

Jawab:

Tidak semua jenis rekening mendapatkan bunga.

Algoritma & Pemrograman 2 -

(8)

Hirarki

Pewarisan (3)

• Inheritance : mekanisme untuk memperluas

class yang ada dengan menambah instance

variable dan method, contoh:

• Subclass mewarisi method dari superclass:

public class

 

SavingsAccount

 

extends

 

BankAccount

{

     // Tambahkan instance variables

     // Tambahkan method-method baru

}

// Rekening tabungan dengan rate bunga 10%

SavingsAccount collegeFund = new SavingsAccount(10);

// Menjalankan method BankAccount dengan object  SavingsAccount 

collegeFund.deposit(500);

(9)

Hirarki

Pewarisan (4)

• Dalam subclass:

– Tambahkan instance variable

– Tambahkan method(-method) baru, dan

– Ubah/override method

Algoritma & Pemrograman 2 -

TIF2202 9

public

class

SavingsAccount

extends

BankAccount {

      // Instance variable(s)

private

double interestRate;

public

SavingsAccount

(double rate){

// Implementasi constructor

}

public

void

addInterest

(){

      

// Implementasi method

}

}

(10)

Hirarki

Pewarisan (5)

• Instance variable yang dideklarasikan dalam

superclass, hadir dalam object subclass.

• Object SavingsAccount mewarisi instance

variable balance dari class BankAccount, dan

mendapat 1 instance variable tambahan, yaitu

(11)

Hirarki

Pewarisan (6)

• Implementasi constructor di subclass

• Implementasi method baru

Algoritma & Pemrograman 2 -

TIF2202 11

public

class

SavingsAccount

extends

BankAccount {

private

double interestRate;

public

SavingsAccount

(double rate)

{

interestRate = rate;

}

public

void addInterest

()

{

double interest = getBalance() * interestRate / 100;

deposit(interest);

}

}

(12)

Hirarki

Pewarisan (7)

• Subclass tidak memiliki akses ke instance variable superclass

yang bersifat private.

• Encapsulation: method addInterest memanggil getBalance

daripada meng-update variabel balance dari superclass (variabel

tsb private)

• Catatan: method addInterest memanggil getBalance tanpa

mengspesifikasikan parameter implisit (pemanggilan tsb

diterapkan ke object yang sama)

• Terakhir, tambahkan

komentar javadoc

dalam program.

Komentar javadoc berada di awal class/method/constructor, diapit

dengan simbol /** dan */

– Di atas deklarasi class: deskripsi, @author, @version

(13)

Class

SavingsAccount

Algoritma & Pemrograman 2 -

TIF2202 13

1

/**

2

An account that earns interest at a fixed rate.

3

*/

4

public

class

SavingsAccount

extends

BankAccount {

5

private

double

interestRate;

6

7

/**

8

Constructs a bank account with a given interest rate.

9

@param rate

the interest rate

10

*/

11

public

SavingsAccount(

double

rate) {

12

interestRate = rate;

13

}

14

15

/**

16

Adds the earned interest to the account balance.

17

*/

18

public

void

addInterest() {

19

double

interest = getBalance() * interestRate /

100

;

20

deposit(interest);

21

}

(14)

Class

BankAccount (1)

1

/**

2

A bank account has a balance that can be changed by

3

deposits and withdrawals.

4

*/

5

public

class

BankAccount {

6

private

double

balance;

7

8

/**

9

Constructs a bank account with a zero balance.

10

*/

11

public

BankAccount() {

12

balance =

0

;

13

}

14

15

/**

16

Constructs a bank account with a given balance.

17

@param initialBalance

the initial balance

18

*/

19

public

BankAccount(

double

initialBalance) {

20

balance = initialBalance;

(15)

Class

BankAccount (2)

Algoritma & Pemrograman 2 -

TIF2202 15 15

23

/**

24

Deposits money into the bank account.

25

@param amount

the amount to deposit

26

*/

27

public

void

deposit(

double

amount) {

28

balance = balance + amount;

29

}

30

31

/**

32

Withdraws money from the bank account.

33

@param amount

the amount to withdraw

34

*/

35

public

void

withdraw(

double

amount) {

36

balance = balance - amount;

37

}

38

39

/**

40

Gets the current balance of the bank account.

41

@return

the current balance

42

*/

43

public

double

getBalance() {

44

return

balance;

45

}

(16)

Mewarisi Class:

Sintaks

(17)

Hirarki

BankAccount -

SavingsAccount

Algoritma & Pemrograman 2 -

TIF2202 17

Class BankAccount

- double balance

Properties:

- void deposit(double amount)

- void withdraw(double amount)

- double getBalance()

Methods:

Constructor:

- BankAccount()

- BankAccount(double initialBalance)

Class SavingsAccount

- double interestRate

Properties:

- void addInterest()

Methods:

Constructor:

- SavingsAccount(double rate)

(18)

Latihan

Perhatikan hirarki class BankAccount –

SavingsAccount.

1.Instance variable apa yang dimiliki object class

SavingsAccount?

2.Sebutkan method yang dapat dijalankan oleh

object SavingsAccount!

Jawab:

3.Dua instance variable: balance dan interestRate.

4.Empat method: deposit, withdraw, getBalance,

dan addInterest.

(19)

Latihan

• Jika class Manager meng-extends class Employee,

class mana yang menjadi superclass dan class

mana yang menjadi subclass?

Jawab:

•. Class

Manager adalah subclass;

class

Employee

adalah superclass.

Algoritma & Pemrograman 2 -

(20)

Kesalahan Umum:

Mengakses Variabel

Private

• Ingat access specifier private!

• Subclass tidak memiliki akses ke instance

variable yang bersifat private.

public

class

SavingsAccount

extends

BankAccount {

private

double interestRate;

public

void

addInterest

()

{

double interest = getBalance() * interestRate / 100;

balance = balance + interest;

}

}

// Error

Variable balance di class

(21)

Kesalahan Umum:

Membayangi Variabel

(1)

• Apakah dengan menambahkan variabel balance di

class SavingsAccount?

• Apa yang terjadi?

• Apa solusinya?

Algoritma & Pemrograman 2 -

TIF2202 21

public

class

SavingsAccount

extends

BankAccount {

private

double interestRate;

private

double balance;

// Menambahkan variabel balance

public

void

addInterest

()

{

double interest = getBalance() * interestRate / 100;

balance = balance + interest;

}

}

Tidak terjadi compile error,

namun tidak akan meng-update

saldo dengan tepat

(22)

Kesalahan Umum:

Membayangi Variabel

(2)

• Method addInterest berhasil di-compile,

tetapi tidak meng-update balance (saldo)

yang tepat!

(23)

Solusi dari

Membayangi

Variabel

• Perhatikan statement berikut:

balance = balance + interest

• Statement di atas mirip dengan statement di mana?

– Ingat method void deposit(double amount)?

– Gunakan/panggil method deposit, namun parameternya

diganti dengan interest.

Algoritma & Pemrograman 2 -

TIF2202 23

public

class

SavingsAccount

extends

BankAccount {

private

double interestRate;

public

void

addInterest

()

{

double interest = getBalance() * interestRate / 100;

balance = balance + interest;

}

}

deposit(interest);

(24)
(25)

Overriding

Method (1)

• Method subclass meng-override

(menimpa) method superclass hanya jika

memiliki nama dan tipe parameter

yang sama seperti pada method

superclass.

– Ketika method X ada di superclass dan

subclass-nya, maka overriding method yang

dieksekusi.

– Overriding method (method yang menimpa)

adalah method di subclass

– Overriden method (method yang ditimpa)

adalah method di superclass

Algoritma & Pemrograman 2 -

(26)

Overriding

Method (2)

• Method deposit dan withdraw dari class

CheckingAccount

override method deposit

dan withdraw dari class BankAccount untuk

menangani biaya transaksi di rekening Cek.

public

class BankAccount {

. . .

public

void deposit(double amount) { . . . }

public

void withdraw(double amount) { . . . }

public

double getBalance() { . . . }

}

public

class CheckingAccount

extends

BankAccount {

. . .

public

void deposit(double amount) { . . . }

public

void withdraw(double amount) { . . . }

public

void deductFees() { . . . }

(27)

Overriding

Method (3)

• Problem: Override method deposit tidak dapat

menambahkan variabel amount ke balance.

• Apa solusinya?

– Gunakan method public di superclass untuk

memodifikasi private instance variable superclass.

Algoritma & Pemrograman 2 -

TIF2202 27

public

class

CheckingAccount

extends

BankAccount {

...

public

void

deposit(double amount) {

transactionCount++;

// Menambahkan amount ke balance

balance = balance + amount;

}

}

(28)

Memanggil Method

di Superclass (1)

• Method deposit dari class CheckingAccount

harus menjalankan method deposit dari

BankAccount.

• Apakah seperti ini?

Algoritma & Pemrograman 2 -

public

class

CheckingAccount

extends

BankAccount {

...

public

void

deposit(double amount) {

transactionCount++;

// Menambahkan amount ke balance

balance = balance + amount;

}

}

deposit(amount);

// Terjadi infinite recursion, karena sama

// dengan 

this.deposit(amount);

Catt: Recursion adalah proses

pemanggilan method diri sendiri

this menunjukkan bahwa method yang

(29)

Memanggil Method

di Superclass (2)

• Untuk memanggil method-method dari

superclass-nya, suatu subclass harus

memanggilnya dengan keyword super.

Algoritma & Pemrograman 2 -

TIF2202 29

public

class

CheckingAccount

extends

BankAccount {

...

public

void

deposit(double amount) {

transactionCount++;

// Menambahkan amount ke balance

deposit(amount);

}

}

super.deposit(amount);

// OK

(30)

Memanggil Method

Superclass: Sintaks

(31)

Memanggil Method

di Superclass (3)

Algoritma & Pemrograman 2 -

TIF2202 31

public

class

CheckingAccount

extends

BankAccount

{

private

static

final int

FREE_TRANSACTIONS

= 3;

private

static final double

TRANSACTION_FEE

= 2.0;

private

int transactionCount

;

. . .

public

void

withdraw

(double amount) {

transactionCount++;

       // Mengurangi amount dari balance

super.

withdraw(amount);

}

public

void

deductFees

() {

if (transactionCount > FREE_TRANSACTIONS){

double fees = TRANSACTION_FEE *

(transactionCount - FREE_TRANSACTIONS);

super.

withdraw(fees);

}

transactionCount = 0;

}

. . .

}

(32)

Hirarki

BankAccount -

SavingsAccount -

CheckingAccount

Class BankAccount

- double balance

Properties:

- void deposit(double amount)

- void withdraw(double amount)

- double getBalance()

Methods:

Constructors:

- BankAccount()

- BankAccount(double initialBalance)

Class SavingsAccount

- double interestRate

Properties:

Methods:

Constructors:

- SavingsAccount(double rate)

Class CheckingAccount

- static final int FREE_TRANSACTIONS

- static final double TRANSACTION_FEE

- int transactionCount

Properties:

- void deposit(double amount)

- void withdraw(double amount)

Methods:

Constructors:

(33)

Latihan

Perhatikan hirarki class BankAccount – SavingsAccount -

CheckingAccount.

Kategorikan method-method dari class SavingsAccount dan

CheckingAccount, apakah termasuk method yang inherited

(diwarisi), new (baru), atau overriding (menimpa)?

Jawab:

1.

Class SavingsAccount:

– Inherited (diwarisi) : deposit, withdraw, getBalance

– New (baru): addInterest

2.

Class CheckingAccount:

– Overriding (menimpa) : deposit, withdraw

– Inherited (diwarisi) : getBalance

– New (baru): deductFees

Algoritma & Pemrograman 2 -

(34)

Latihan

• Mengapa method withdraw dari class

CheckingAccount memanggil super.withdraw?

Jawab:

•. Karena perlu mereduksi balance, dan tidak dapat

mengakses variabel balance di class BankAccount

secara langsung.

(35)

Latihan

• Mengapa method

deductFees

menge-set

transactionCount ke nilai 0?

Jawab:

• Karena transactionCount merefleksikan jumlah

transaksi dari bulan yang berjalan.

Algoritma & Pemrograman 2 -

(36)
(37)

Constructor

Subclass (1)

• Untuk memanggil constructor dari

superclass-nya, suatu subclass harus memanggilnya

dengan keyword super yang diletakkan pada

statement pertama di constructor subclass.

Algoritma & Pemrograman 2 -

TIF2202 37

public

class

CheckingAccount

extends

BankAccount {

...

public

CheckingAccount(double initialBalance) {

       // Mengkonstruksikan superclass dengan memanggil 

       // constructor superclass dengan 1 parameter

super(initialBalance);

// Inisialisasi transactionCount

transactionCount = 0;

}

}

(38)

Constructor

Subclass (2)

• Ketika constructor subclass tidak

memanggil constructor superclass,

superclass harus memiliki constructor

tanpa parameter

– Jika superclass tidak memiliki constructor tanpa

(39)

1

/**

2

A checking account that charges transaction fees.

3

*/

4

public

class

CheckingAccount

extends

BankAccount {

5

private

static

final

int

FREE_TRANSACTIONS =

3

;

6

private

static

final

double

TRANSACTION_FEE =

2.0

;

7

8

private

int

transactionCount;

9

10

/**

11

Constructs a checking account with a given balance.

12

@param initialBalance

the initial balance

13

*/

14

public

CheckingAccount(

double

initialBalance) {

15

//

Construct superclass

16

super

(initialBalance);

17

18

//

Initialize transaction count

19

transactionCount =

0

;

20

}

21

22

public

void

deposit(

double

amount) {

23

transactionCount++;

24

//

Now add amount to balance

25

super

.deposit(amount);

26

}

Class

CheckingAccount

(1)

Algoritma & Pemrograman 2 -

(40)

27

28

public

void

withdraw(

double

amount) {

29

transactionCount++;

30

//

Now subtract amount from balance

31

super

.withdraw(amount);

32

}

33

34

/**

35

Deducts the accumulated fees and resets the

36

transaction count.

37

*/

38

public

void

deductFees() {

39

if

(transactionCount > FREE_TRANSACTIONS) {

40

double

fees = TRANSACTION_FEE *

41

(transactionCount - FREE_TRANSACTIONS);

42

super

.withdraw(fees);

43

}

44

transactionCount =

0

;

45

}

46

}

Class

CheckingAccount

(2)

(41)

Memanggil

Constructor

Superclass: Sintaks

Algoritma & Pemrograman 2 -

(42)

Latihan

1. Mengapa constructor

SavingsAccount

tidak memanggil

constructor superclass?

2. Kapan menjalankan method superclass dengan keyword

super

, apakah pemanggilan tsb harus statement pertama dari

method subclass?

Jawab:

1. Karena constructor

SavingsAccount

menggunakan default

constructor superclass, dimana menge-set saldo (balance) 0.

2. Tidak — hal ini persyaratan hanya untuk constructor.

Contohya, method

SavingsAccount.deposit

pertamanya

meng-increment jumlah transaksi, lalu memanggil method

superclass.

(43)

KONVERSI ANTARA TIPE

SUBCLASS DAN

SUPERCLASS

Algoritma & Pemrograman 2 -

(44)

Konversi Tipe

Subclass

ke Superclass

SavingsAccount danaKuliah = new SavingsAccount(10);

BankAccount rek = danaKuliah; // OK, konversi subclass ke superclass

Object obj = rek; // OK, konversi subclass ke superclass

• Konversi dari reference subclass ke

reference superclass:

danaKuliah

=

rek =

obj =

• Semua variabel reference menunjuk ke tipe object SavingsAccount.

• Catatan: Class Object adalah superclass dari semua class.

(45)

Konversi Tipe

Superclass ke

Subclass (1)

Algoritma & Pemrograman 2 -

TIF2202 45

SavingsAccount danaKuliah = new SavingsAccount(10);

BankAccount rek = danaKuliah;

rek.deposit(1000); // OK

rek.addInterest(); // Error, karena addInterest bukan di class BankAccount

• Terkadang perlu mengkonversi dari reference

superclass ke reference subclass:

• Casting berbahaya, jika salah bisa melempar

exception

• Solusi: Gunakan operator instanceof

sebelum konversi superclass ke subclass.

(46)

Konversi Tipe

Superclass

ke Subclass (2)

• Operator instanceof untuk menguji apakah

sebuah object benar bertipe tertentu.

if (obj instanceof BankAccount) {

BankAccount rek = (BankAccount) obj;

...

(47)

Operator

instanceOf

:

Sintaks

Algoritma & Pemrograman 2 -

(48)

POLIMORFISME DAN

PEWARISAN

(49)

Polimorfisme

dan

Pewarisan (1)

Algoritma & Pemrograman 2 -

TIF2202 49

• Perhatikan source code berikut ini:

• Method deposit manakah yang dipanggil?

• Dynamic method lookup: mekanisme

untuk memanggil overridden method yang

dilakukan saat run time

// rekTabungan1 menyimpan reference ke SavingsAccount

BankAccount rekTabungan1 = new SavingsAccount(1000);

// rekCek1 menyimpan reference ke CheckingAccount

BankAccount rekCek1 = new CheckingAccount(500);

rekCek1.deposit(1000);

// rekCek2 menyimpan reference ke CheckingAccount

BankAccount rekCek2 = new CheckingAccount(1500);

(50)

Polimorfisme

dan

Pewarisan (2)

• Perhatikan source code di class

CheckingAccount berikut ini:

• Ketika Anda memanggil:

• Terjadi pemanggilan 2 method berikut:

public void transfer(double amount, BankAccount other){

withdraw(amount);

other.deposit(amount);

}

rekCek1.transfer(1000, rekCek2);

rekCek1.withdraw(1000);

rekCek2.deposit(1000);

(51)

Polimorfisme

dan

Pewarisan (3)

Algoritma & Pemrograman 2 -

TIF2202 51

• Polymorphism: kemampuan untuk

memperlakukan object yang memiliki

behavior yang berbeda, dengan cara yang

seragam

• Pemanggilan method di method transfer

sama dengan :

• this dapat menunjuk ke BankAccount

atau sebuah object subclass-nya.

withdraw(amount);

(52)

1

/**

2

This program tests the BankAccount class and

3

its subclasses.

4

*/

5

public

class

AccountTester {

6

public

static

void

main(String[] args) {

7

SavingsAccount momsSavings =

new

SavingsAccount(

0.5

);

8

9

CheckingAccount harrysChecking =

new

CheckingAccount(

100

);

10

11

momsSavings.deposit(

10000

);

12

13

momsSavings.transfer(

2000

, harrysChecking);

14

harrysChecking.withdraw(

1500

);

15

harrysChecking.withdraw(

80

);

16

17

momsSavings.transfer(

1000

, harrysChecking);

18

harrysChecking.withdraw(

400

);

19

Class

AccountTester

(1)

(53)

20

//

Simulate end of month

21

momsSavings.addInterest();

22

harrysChecking.deductFees();

23

24

System.out.println(

"Mom’s savings balance: "

25

+ momsSavings.getBalance());

26

System.out.println(

"Expected: 7035"

);

27

28

System.out.println(

"Harry’s checking balance: "

29

+ harrysChecking.getBalance());

30

System.out.println(

"Expected: 1116"

);

31

}

32

}

Class

AccountTester

(2)

Algoritma & Pemrograman 2 -

TIF2202 53

Output program AccountTester:

Mom's savings balance: 7035.0

Expected: 7035

Harry's checking balance: 1116.0

Expected: 1116

(54)

Latihan

1. Mengapa parameter kedua dari method

transfer

harus

bertipe

BankAccount

dan tidak, sebagai contoh,

SavingsAccount

?

2. Mengapa kita tidak dapat mengubah parameter kedua dari

method

transfer

menjadi tipe

Object

?

Jawab:

1. Kita ingin menggunakan method untuk semua jenis bank

account. Jika kita menggunakan tipe parameter

SavingsAccount

, kita tidak dapat memanggil method

dengan object

CheckingAccount

.

2. Kita tidak dapat menjalankan method

deposit

pada

(55)

Latihan

1. Jika

a

adalah variabel bertipe

BankAccount

yang

menyimpan non-

null

reference, apa yang Anda tahu

tentang object yang

a

tunjuk?

2. Jika

a

menunjuk ke checking account, apa efek dari

pemanggilan

a.transfer(1000, a)

?

Jawab:

1. Object adalah sebuah instan dari

BankAccount

atau

satu dari subclass-nya.

2. Saldo dari

a

tidak berubah, dan transaction

di-increment 2x.

Algoritma & Pemrograman 2 -

(56)

ACCESS SPECIFIER

PROTECTED

(57)

Akses protected

(1)

Algoritma & Pemrograman 2 -

TIF2202 57

• Fitur protected dapat diakses oleh

seluruh subclass dan oleh class dalam

package yang sama.

• Menyelesaikan problem dimana method di

class

CheckingAccount

membutuhkan

akses ke instance variable

balance

dari

superclass

BankAccount

:

public class BankAccount {

protected double balance;

. . .

}

(58)

Akses protected

(2)

Algoritma & Pemrograman 2 -

TIF2202 58

• Perancang superclass tidak memiliki

kontrol terhadap pembuat subclass:

• Sembarang method subclass dapat mengkorupsi data

superclass

• Class-class dengan instance variable protected sulit

dimodifikasi — variabel bertipe protected tidak dapat

diubah, karena seseorang di luar sana mungkin telah

menulis subclass yang mana code bergantung terhadap

variabel tsb

• Data protected dapat diakses oleh seluruh

method dari class dalam package yang sama.

• Pilihan yang terbaik untuk meninggalkan seluruh

data dalam kondisi private dan menyediakan

Referensi

Dokumen terkait

untuk kegiatan layanan yang terdiri dari ruang baca umum, ruang layanan.. sirkulasi, ruang layanan referensi, ruang layanan terbitan berkala,

Seluruh perhitungan konstruksi lambung kapal beserta rekomendasinya adalah mengambil dari buku peraturan BKI Volume II 2006 dan ABS 1993 mengenai peraturan

Penelitian berjudul Analisis Faktor Yang Mempengaruhi Pengeluaran Konsumsi Rumah Tangga Di Desa Petung Kecamatan Bangsalsari Kabupaten Jember ini bertujuan untuk

Analisis data dan pengujian hipotesis dalam penelitian ini akan dilakukan dengan menggunakan model regresi linier berganda, dimana dalam analisis regresi tersebut akan menguji

Hasil dari pengembangan e-Learning meliputi knowledge map dengan menggunakan aplikasi mindjet manager yang dikostumisasi dengan memperhatikan kebutuhan user dan user

[r]

Dari data-data percobaan yang telah dilakukan dalam penelitian pengeringan kelopak bunga Rosela ini dapat diambil kesimpulan bahwa suhu 80 0 C merupakan suhu yang efektif

[r]