BAB 6: Object-Oriented Programming
BAB 6: Object-Oriented Programming (OOP)
6.1 Class dan Object
Pengenalan Class
Class adalah blueprint atau template untuk membuat object. Class mendefinisikan properti dan method yang akan dimiliki oleh object.
// Contoh class sederhana
class Person {
// Properties (attributes)
String name;
int age;
// Methods
void sayHello() {
print('Hello, my name is $name');
}
void haveBirthday() {
age++;
print('Happy birthday! Now I am $age years old');
}
}
void main() {
// Membuat object dari class Person
var person1 = Person();
person1.name = 'Budi';
person1.age = 25;
// Mengakses method
person1.sayHello();
person1.haveBirthday();
}
Properties dan Methods
class Car {
// Properties
String brand;
String model;
int year;
int _mileage = 0; // Private property
// Getter
int get mileage => _mileage;
// Setter
set mileage(int value) {
if (value >= 0) {
_mileage = value;
}
}
// Method
void drive(int kilometers) {
if (kilometers > 0) {
_mileage += kilometers;
print('Driving $kilometers km. Total mileage: $_mileage');
}
}
// Method dengan return value
String getInfo() {
return '$year $brand $model';
}
}
6.2 Constructor
Default Constructor
class Student {
String name;
int age;
// Default constructor
Student(this.name, this.age);
void introduce() {
print('Hi, I am $name and I am $age years old');
}
}
Named Constructor
class Rectangle {
double width;
double height;
// Regular constructor
Rectangle(this.width, this.height);
// Named constructor
Rectangle.square(double size)
: width = size,
height = size;
// Named constructor with initializer list
Rectangle.fromMap(Map<String, double> map)
: width = map['width'] ?? 0,
height = map['height'] ?? 0;
double get area => width * height;
}
void main() {
var rect1 = Rectangle(10, 5);
var rect2 = Rectangle.square(10);
var rect3 = Rectangle.fromMap({'width': 10, 'height': 5});
}
Factory Constructor
class Database {
static Database? _instance;
// Private constructor
Database._internal() {
print('Database initialized');
}
// Factory constructor
factory Database() {
return _instance ??= Database._internal();
}
}
6.3 Inheritance
Basic Inheritance
// Base/Parent class
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('Some generic sound');
}
}
// Child class
class Dog extends Animal {
Dog(String name) : super(name);
// Method overriding
@override
void makeSound() {
print('Woof!');
}
// Additional method
void fetch() {
print('$name is fetching the ball');
}
}
// Another child class
class Cat extends Animal {
Cat(String name) : super(name);
@override
void makeSound() {
print('Meow!');
}
}
Abstract Class
abstract class Shape {
// Abstract method (no implementation)
double getArea();
double getPerimeter();
// Regular method with implementation
void printInfo() {
print('Area: ${getArea()}');
print('Perimeter: ${getPerimeter()}');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double getArea() => 3.14 * radius * radius;
@override
double getPerimeter() => 2 * 3.14 * radius;
}
6.4 Encapsulation
Private Members dan Getters/Setters
class BankAccount {
String _accountNumber;
double _balance = 0;
BankAccount(this._accountNumber);
// Getter
double get balance => _balance;
String get accountNumber => _accountNumber;
// Method untuk deposit
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
print('Deposited: \$${amount.toStringAsFixed(2)}');
print('New balance: \$${_balance.toStringAsFixed(2)}');
}
}
// Method untuk withdrawal
bool withdraw(double amount) {
if (amount > 0 && amount <= _balance) {
_balance -= amount;
print('Withdrawn: \$${amount.toStringAsFixed(2)}');
print('New balance: \$${_balance.toStringAsFixed(2)}');
return true;
}
print('Insufficient funds');
return false;
}
}
6.5 Praktek: Program Sistem Perpustakaan Sederhana
import 'dart:io';
// Class untuk merepresentasikan buku
class Book {
String id;
String title;
String author;
bool isAvailable;
DateTime? borrowedDate;
String? borrowedBy;
Book(this.id, this.title, this.author) : isAvailable = true;
// Method untuk meminjam buku
bool borrow(String memberName) {
if (isAvailable) {
isAvailable = false;
borrowedDate = DateTime.now();
borrowedBy = memberName;
return true;
}
return false;
}
// Method untuk mengembalikan buku
void returnBook() {
isAvailable = true;
borrowedDate = null;
borrowedBy = null;
}
// Method untuk menampilkan info buku
void displayInfo() {
print('ID: $id');
print('Judul: $title');
print('Penulis: $author');
print('Status: ${isAvailable ? "Tersedia" : "Dipinjam"}');
if (!isAvailable) {
print('Dipinjam oleh: $borrowedBy');
print('Tanggal pinjam: ${_formatDate(borrowedDate!)}');
}
}
String _formatDate(DateTime date) {
return '${date.day}/${date.month}/${date.year}';
}
}
// Class untuk merepresentasikan member perpustakaan
class LibraryMember {
String id;
String name;
List<Book> borrowedBooks;
LibraryMember(this.id, this.name) : borrowedBooks = [];
void displayInfo() {
print('ID Member: $id');
print('Nama: $name');
print('Jumlah buku dipinjam: ${borrowedBooks.length}');
}
}
// Class utama untuk manajemen perpustakaan
class Library {
List<Book> _books = [];
List<LibraryMember> _members = [];
// Menambah buku baru
void addBook(String title, String author) {
String id = 'B${_books.length + 1}';
_books.add(Book(id, title, author));
print('\n✓ Buku berhasil ditambahkan!');
}
// Menambah member baru
void addMember(String name) {
String id = 'M${_members.length + 1}';
_members.add(LibraryMember(id, name));
print('\n✓ Member berhasil ditambahkan!');
}
// Menampilkan semua buku
void displayBooks() {
if (_books.isEmpty) {
print('\nBelum ada buku di perpustakaan');
return;
}
print('\n=== DAFTAR BUKU ===');
for (var book in _books) {
print('\n-------------------');
book.displayInfo();
}
}
// Menampilkan semua member
void displayMembers() {
if (_members.isEmpty) {
print('\nBelum ada member terdaftar');
return;
}
print('\n=== DAFTAR MEMBER ===');
for (var member in _members) {
print('\n-------------------');
member.displayInfo();
}
}
// Meminjam buku
void borrowBook(String bookId, String memberId) {
var book = _findBook(bookId);
var member = _findMember(memberId);
if (book == null) {
print('\nBuku tidak ditemukan!');
return;
}
if (member == null) {
print('\nMember tidak ditemukan!');
return;
}
if (book.borrow(member.name)) {
member.borrowedBooks.add(book);
print('\n✓ Buku berhasil dipinjam!');
} else {
print('\nBuku tidak tersedia untuk dipinjam!');
}
}
// Mengembalikan buku
void returnBook(String bookId, String memberId) {
var book = _findBook(bookId);
var member = _findMember(memberId);
if (book == null || member == null) {
print('\nBuku atau member tidak ditemukan!');
return;
}
if (!book.isAvailable && book.borrowedBy == member.name) {
book.returnBook();
member.borrowedBooks.remove(book);
print('\n✓ Buku berhasil dikembalikan!');
} else {
print('\nBuku tidak dapat dikembalikan!');
}
}
// Helper methods
Book? _findBook(String id) {
return _books.firstWhere((book) => book.id == id,
orElse: () => throw 'Book not found');
}
LibraryMember? _findMember(String id) {
return _members.firstWhere((member) => member.id == id,
orElse: () => throw 'Member not found');
}
}
void main() {
var library = Library();
while (true) {
print('\n=== SISTEM PERPUSTAKAAN ===');
print('1. Tambah Buku');
print('2. Tambah Member');
print('3. Lihat Daftar Buku');
print('4. Lihat Daftar Member');
print('5. Pinjam Buku');
print('6. Kembalikan Buku');
print('7. Keluar');
stdout.write('\nPilih menu (1-7): ');
String? input = stdin.readLineSync();
switch (input) {
case '1':
stdout.write('\nJudul buku: ');
String? title = stdin.readLineSync();
stdout.write('Penulis: ');
String? author = stdin.readLineSync();
if (title != null && author != null) {
library.addBook(title, author);
}
case '2':
stdout.write('\nNama member: ');
String? name = stdin.readLineSync();
if (name != null) {
library.addMember(name);
}
case '3':
library.displayBooks();
case '4':
library.displayMembers();
case '5':
stdout.write('\nID Buku: ');
String? bookId = stdin.readLineSync();
stdout.write('ID Member: ');
String? memberId = stdin.readLineSync();
if (bookId != null && memberId != null) {
library.borrowBook(bookId, memberId);
}
case '6':
stdout.write('\nID Buku: ');
String? bookId = stdin.readLineSync();
stdout.write('ID Member: ');
String? memberId = stdin.readLineSync();
if (bookId != null && memberId != null) {
library.returnBook(bookId, memberId);
}
case '7':
print('\nTerima kasih telah menggunakan Sistem Perpustakaan!');
return;
default:
print('\nMenu tidak valid!');
}
}
}
Latihan Mandiri
Tambahkan fitur untuk mengedit informasi buku dan member
Implementasikan sistem denda untuk keterlambatan pengembalian
Tambahkan fitur pencarian buku berdasarkan judul atau penulis
Buat sistem reservasi buku yang sedang dipinjam
Implementasikan fitur untuk melihat history peminjaman
Tips OOP
Gunakan private members (diawali dengan _) untuk encapsulation
Manfaatkan inheritance untuk mengurangi duplikasi kode
Gunakan abstract class untuk template yang akan diimplementasikan
Pilih constructor yang sesuai dengan kebutuhan
Validasi input di constructor atau setter
Gunakan getter/setter untuk akses kontrol yang lebih baik
Dokumentasikan kode dengan baik
Terapkan prinsip Single Responsibility
Last updated