Anda diminta untuk membuat sistem kasir suatu toko yang menjual alat musik dan barang elektronik. Toko tersebut memiliki sistem membership untuk pelanggan yang dibagi menjadi 3: Premium, Gold, dan Silver, masing-masing memiliki potongan harga 10%, 7.5% dan 5% dan jika tidak menjadi member maka tidak mendapatkan potongan (diperiksa dengan atribut isMember dan memberType). Selain itu, karyawan toko tersebut jika membeli juga dapat memiliki potongan sendiri yaitu 12.5%.
2. Barang-barang tertentu dapat diberi potongan tertentu sesuai kategorinya (menggunakan interface seperti di diagram). Ketentuannya alat musik dapat memiliki diskon maksimal 15% dan barang elektronik maksimal 20%. Penghitungan diskon ini dicek terlebih dahulu atribut onSale-nya apabila true maka diskon bisa diterapkan begitu pula sebaliknya.
Opsional, Toko tersebut dapat menerapkan sistem voucher. Anda dapat menentukan sendiri kode vouchernya dan besaran potongannya. Ketentuan lainnya adalah kode voucher memiliki rentang tanggal berlaku, dan hanya bisa di-apply apabila tanggal pada PC anda ada dalam rentang tanggal tersebut. Gunakan fungsi yang sudah disediakan di java.util.Date perhatikan apakah tanggal di PC anda sebelum tanggal yang tertera di attribut validityPeriod jika tidak getDiscount() akan menampilkan voucher tidak valid dan mengembalikan nilai 0, tetapi program tetap berjalan. Hint:
Harga per barang diambil dengan method getPrice() dan harus sudah dihitung
dengan diskon per barang-nya. • Objek dari class Cashier digunakan untuk melakukan penjualan, method setPrice() digunakan untuk menambah harga dari barang yang ditambahkan, method setDisc() digunakan untuk menambahkan potongan harga dari membership (dan karyawan) dan voucher. Sedangkan method getTotal() akan menampilkan harga akhir.
4. Jelaskan kepada asisten Anda kapan harus menggunakan abstract class atau interface!
public Voucher(String code, double discount, Date from, Date to) {
this.code = code;
this.discount = discount;
this.validityPeriod = new Date(from, to);
}
public double getDiscount() {
Date today = new Date();
if (today.before(validityPeriod)) {
return discount;
} else {
System.out.println("Invalid voucher!");
return 0;
}
}
}
public class Cashier {
private double total;
private boolean isMember;
private MemberType memberType;
private Voucher voucher;
public Cashier() {
total = 0;
isMember = false;
memberType = null;
voucher = null;
}
public void setPrice(double price) {
total += price;
}
public void setMember(MemberType memberType) {
isMember = true;
this.memberType = memberType;
total *= (1 - memberType.getDiscount());
}
public void setVoucher(Voucher voucher) {
this.voucher = voucher;
total -= voucher.getDiscount();
}
public double getTotal() {
return total;
}
}
```
We use abstract class Item to represent the items that can be purchased. Music and Electronic extends Item to provide the specific discount policy. We use interface MemberType, Discountable and implement them in the member types and items respectively. Voucher is used to provide voucher discount. The Cashier class is used to calculate the total price by applying member discounts, item discounts and voucher discounts.
We use abstract class and interface in this case for:
Abstract class:
- When we want to have some common attributes and methods, but the implementation of some methods may differ. In this case, the getDiscount() method.
- To act as a base class to be extended by concrete classes.
Interface:
- When we want to specify the methods that classes need to implement, but not provide the implementation. In this case, the MemberType and Discountable interfaces.
- To act as a "contract" that classes agree to follow.
So in summary, we use abstract class for partial implementation and interface for specification only. Abstract classes can have implementation, interfaces cannot.
Here is the Java program:
```java
import java.util.Date;
interface Discountable {
public double getDiscount();
}
abstract class Item implements Discountable {
protected String name;
protected double price;
protected boolean onSale = false;
public Item(String name, double price) {
this.name = name;
this.price = price;
}
public double getPrice() {
if (onSale) {
return price * (1 - getDiscount());
}
return price;
}
public abstract double getDiscount();
}
class Music extends Item {
public Music(String name, double price) {
super(name, price);
}
public double getDiscount() {
if (onSale) {
return 0.15;
}
return 0;
}
}
class Electronic extends Item {
public Electronic(String name, double price) {
super(name, price);
}
public double getDiscount() {
if (onSale) {
return 0.2;
}
return 0;
}
}
interface MemberType {
public double getDiscount();
}
class PremiumMember implements MemberType {
public double getDiscount() {
return 0.1;
}
}
class GoldMember implements MemberType {
public double getDiscount() {
return 0.075;
}
}
class SilverMember implements MemberType {
public double getDiscount() {
return 0.05;
}
}
class Voucher {
private String code;
private double discount;
private Date validityPeriod;
public Voucher(String code, double discount, Date from, Date to) {
this.code = code;
this.discount = discount;
this.validityPeriod = new Date(from, to);
}
public double getDiscount() {
Date today = new Date();
if (today.before(validityPeriod)) {
return discount;
} else {
System.out.println("Invalid voucher!");
return 0;
}
}
}
public class Cashier {
private double total;
private boolean isMember;
private MemberType memberType;
private Voucher voucher;
public Cashier() {
total = 0;
isMember = false;
memberType = null;
voucher = null;
}
public void setPrice(double price) {
total += price;
}
public void setMember(MemberType memberType) {
isMember = true;
this.memberType = memberType;
total *= (1 - memberType.getDiscount());
}
public void setVoucher(Voucher voucher) {
this.voucher = voucher;
total -= voucher.getDiscount();
}
public double getTotal() {
return total;
}
}
```
We use abstract class Item to represent the items that can be purchased. Music and Electronic extends Item to provide the specific discount policy. We use interface MemberType, Discountable and implement them in the member types and items respectively. Voucher is used to provide voucher discount. The Cashier class is used to calculate the total price by applying member discounts, item discounts and voucher discounts.
We use abstract class and interface in this case for:
Abstract class:
- When we want to have some common attributes and methods, but the implementation of some methods may differ. In this case, the getDiscount() method.
- To act as a base class to be extended by concrete classes.
Interface:
- When we want to specify the methods that classes need to implement, but not provide the implementation. In this case, the MemberType and Discountable interfaces.
- To act as a "contract" that classes agree to follow.
So in summary, we use abstract class for partial implementation and interface for specification only. Abstract classes can have implementation, interfaces cannot.