Praktikum OOP kedua (26022011)


Jadi gw akan nyoba membahas tentang praktikum OOP kedua ini. Alasannya ada beberapa teman yang ga selesai walau udah dikasi waktu tambahan 24 jam. Untuk link soalnya bisa diunduh disini. Oke langsung aja deh. Oia, ingat ya, gw ga bermaksud menggurui, hanya berusaha membantu dan menambah pemahaman gw juga.

  1. Nambah method
  2. Kelas generik
  3. Inheritance


Nomor 1

yang ini gampang lah ya, tinggal ambil aja praktikum yang pertama baru kemudian ditambah method2 yang baru. Yang perlu diperhatikan adalah method LT. Di soalnya ada kalimat “Perhatikan bahwa current object tidak dipakai.”. Nah, ini berarti method ini dapat dipanggil tanpa memerlukan sebuah object yang udah terinstansiasi. Dengan kata lain sebuah class method, bukan object method. Untuk membuat sebuah class method cukup dengan menambahkan kata kunci static. Coba liat deh potongan codenya, kalo ngomong doang mah ga ngerti

	//file point.h
	....
	static int LT(const Point&,const Point&);

Perhatikan tipenya, gw ngebuat fungsinya menggunakan parameter pass by reference agar tidak dibuat objek yang baru. Trus ntar objek aslinya berubah dong? Makanya ditambah kata kunci const dengan tujuan agar objek tersebut terjamin ga berubah. Kenapa dibuat seperti ini?

  • kita tau fungsi LT tidak mengubah objek yang di oper (di pass) di parameter
  • agar tidak menggunakan copy constructor. Kalo ga make pass by reference, maka akan digunakan copy constructor untuk ngebuat objek tersebut

Lalu gimana realisasi method tersebut? Nih code bodynya gw:

int Point::LT(const Point& a, const Point& b) {
	if (a.GetX() < b.GetX() && a.GetY() < b.GetY()) {
		return 1;
	}
	return 0;
}

Jelaslah ya? Oh iya, trus gimana makenya? Contohnya gini nih:

int main() {
	Point P1(3,2);
	Point P2(P1);
	P2.Mirror();
	Point P3;
	P3 = P2.MirrorOf();
	if (Point::LT(P2,P3)) {
		cout << "P2 < P3\n";
	} else {
		cout << "P2 >= P3\n";
	}
}

Jadi tidak dibutuhkan sebuah objek agar bisa digunakan method tersebut. Ga perlu Object.Method(), tapi Class::Method(). Begitu.

Trus ini nih, di code gw kan ada

P3 = P2.MirrorOf();"

Agar berjalan dengan benar, maka harus udah dideklarasikan juga operator= yang merupakan salah satu dari 4 sekawan🙂 Kalo ga, mungkin akan bisa dicompile, tapi yang dilakukannya adalah shallow copy, bukan mengcopy objek.
Hmm gw rasa untuk nomor 1 okelah ya? Kalau ada pertanyaan tanya aja sebisa mungkin gw jawab.

Nomor 2

Jadi di nomor 2 itu kita ngebuat Kelas Generik. Apasih kelas itu? Maksudnya apa sih? Untuk apa? Nah gini nih. Misalnya lu punya procedure swap. deklarasinya kira2 gini lah ya:

void swap(int& a, int& b) {
	int c;
	c = a;
	a = b;
	b = c;
}

Masih ngerti kan? Nah masalahnya gini, kalo misalnya itu procedure dipake buat tipe lain gimana? Naaaaaah. Buat procedure lain kan? Untuk float, trus belum lagi untuk char, trus belum lagi kalo untuk kelas buatan sendiri atau tipe bentukan atau lain2nya. Makanya nih, ada kelas generik kaya gini. Jadi, dengan ngedeklarasiin satu fungsi bisa digunain untuk berbagai tipe.
Jadi procedure swap tadi bisa dibuat kaya gini

template<class T>
void swap<T a, T b>{
	T c;
	c = a;
	a = b;
	b = c;
}

Nah kira-kira fungsi template itu kaya gitu. Kembali ke kelas generik. Itu artinya kelasnya bisa dipake untuk berbagai tipe kan? Nah kita ambil contoh dari salah satu contoh STL, yaitu vector. Vector itu sama kaya ADT array, tapi lebih efisien, dan diimplementasikan dengan baik. Jadi array keren tinggal pake. DAN kalo di ADT, untuk bisa dipake tipe yang beda, musti ganti infotype nya kan di headernya? Nahhhh kalo kelas generik ga perlu repot gitu. Pas ngebuat objectnya, langsung jadi sekalian sesuai tipenya.

template <class T>
class GPoint
{
private:
      T x,y;
public:
      // contructor
      GPoint();
      GPoint(T,T);
      // copy constructor
      GPoint(const GPoint<T>&);
      // destructor
      ~GPoint();
      T GetX() const;
      T GetY() const;
      void SetX(T);
      void SetY(T);
	  static int LT(const GPoint<T>& ,const GPoint<T>&);
	  int operator<(const GPoint<T>&);
	  int IsOrigin();
	  void Mirror();
	  GPoint<T> MirrorOf();
	  void PrintObj();
};

Jadi T itu adalah merupakan sebuah tipe umum, atau bisa kelas juga. Kenapa bisa begitu? Coba liat di line 1, nah, T merupakan class yang dideklarasikan sebagai sebuah template.
Untuk bodinya kita ambil 2 contoh:

template <class T>
int GPoint<T>::LT(const GPoint<T>& a, const GPoint<T>& b) {
	if (a.GetX() < b.GetX() && a.GetY() < b.GetY()) {
		return 1;
	}
	return 0;
}

template <class T>
GPoint<T> GPoint<T>::MirrorOf(){
	GPoint<T> P;
	P.SetX(this->GetX()*-1);
	P.SetY(this->GetY()*-1);
	return P;
}

Untuk setiap body method, diawali dengan kata kunci template diikuti “tipe” yang menjadi “tipe” generik, yang di kode ini hanya T. Lalu untuk kelasnya kan GPoint, TAPI, karena ada template di deklarasi kelasnya, maka harus ada juga deklarasi menggunakan kelas apa, karena kelasnya adalah T, makanya jadi GPoint, coba liat aja deh di main nya gimana supaya jadi kebayang.

int main() {
	GPoint<float> P1(4.3,2.1);
	GPoint<float> P2(P1);
	P2.Mirror();
	GPoint<float> P3;
	P3 = P2.MirrorOf();
	P1.SetX(0);
	P1.SetY(0);
	if (GPoint<float>::LT(P2,P3)) {
		cout << "P2 < P3\n";
	} else {
		cout << "P2 >= P3\n";
	}
	return 0;
}

Itu untuk tipe float, dan kita bisa juga menggunakan tipe int.

int main() {
	GPoint<int> P1(4.3,2.1);
	GPoint<int> P2(P1);
	P2.Mirror();
	GPoint<int> P3;
	P3 = P2.MirrorOf();
	P1.SetX(0);
	P1.SetY(0);
	if (GPoint<int>::LT(P2,P3)) {
		cout << "P2 < P3\n";
	} else {
		cout << "P2 >= P3\n";
	}
	return 0;
}

Lanjut deh nomor 3 ya.

Nomor 3

Untuk nomor 3 ini inheritance. Ya inherit. Gampang kok. Teorinya udah ngerti semua kan? Ya udah, tinggal deklarasiin aja kelas si anak

class Point3D: public Point
{
//deklarasi method dan variable
...
      Point3D(int,int,int);//karena sekarang ada z, jadinya semuanya ada 3.
Point3D MirrorOf(); // tipe kembaliannya juga berubah
static int LT(const Point3D&,const Point3D&); // parameternya juga dong
...
}

Yang perlu diperhatikan kalo di bapaknya dideklarasi sebagai private, tentunya ga bisa dipake di anaknya kan? Nah caranya jadi kaya gini nih

Point3D::Point3D(int newX, int newY, int newZ)
{
      this->SetX(newX); // x dan y privat di kelas bapaknya, sehingga kelas ini ga bisa
      this->SetY(newY); // ngakses kecuali pake method publicnya.
      z = newZ; // z dideklarasi di kelas Point3D ini sendiri, makanya, walau privat tetap bisa diakses
}

wah.. jadi ribet yak? Kalau ngerasa gitu, buka aja akses dari sibapak untuk anaknya. Gimana? Ubah si X ama si Y yang tadinya private jadinya protected, sehingga si anak bisa ngakses punya si bapak. Jadi yang kaya gini bisa dipake nih:

Point3D::Point3D(int newX, int newY, int newZ)
{
      x = newX;
      y = newY
      z = newZ;
}

Kalo ada yang ga ngerti tanya aja ya, gw coba bantuin deh.🙂

2 thoughts on “Praktikum OOP kedua (26022011)

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s