Object-Oriented Programming เนื้อหาไฟนอล 2023/1

September 6, 2023

แนวข้อสอบ

มี 3 ตอน เก็บ 40% 87 คะแนน

  • ตอนที่ 1 (40 คะแนน)
    1. หาผลลัพท์โปรแกรม
      • Inheritance / Polymophism / Static Binding / Dynamic Binding
    2. ตอบคำถามเรื่อง
      • Inheritance + implements คราส Interface
    3. เขียนโปรแกรม Interface
    4. ตอบคำถามถูกผิดเกี่ยวกับ ... + interface
    5. เขียนโปรแกรม Dynamic Binding
    6. หาผลลัทธ์ Graphics
  • ตอนที่ 2 เขียนโปรแกรม GUI + Event 2 ข้อ \approx 20 คะแนน
  • ตอนที่ 3 เขียนโปรแกรม Algorithm 2 ข้อ \approx 15 คะแนน

Week 10 Inheritance

OOP Concept

  1. Abstraction: มองทุกอย่างเป็น Class และ object
  2. Encapsulation: การป้องกันข้อมูล
    • Public
    • Private
    • Protected
  3. Inheritance: การสืบทอดคุณสมบัติ
  4. Polymorphism: การมีหลายรูปแบบ
    • Overriding
    • Overloading
    • Dynamic binding
    • Static binding

Type of Classes

  • Super Class หรือ General Class
  • Sub Class: Specific class
    • Class ลูกจะมี Attribute และ Methods เหมือนแม่
    • เช่น Bachelor student: ป. ตรี
// Super Class class A { int x; void f() {} } // Sub Class (B) // From Super Class A class B extends A { int y; void g() {} }
Inheritance example

โดยปกติแล้ว Java จะทำการ Inheritance Class Object อยู่แล้ว (โดยอัตโนมัติ) ซึ่งประกอบไปด้วย Methods ต่างๆ เช่น getClass(), hashCode(), equals(), clone(), toString(), notify(), notifyAll(), wait()

@Override

  • การเปลี่ยน Behavior ของ Methods ใน Sub Class ที่ Inheritance มาจาก Super Class ด้วยการ @Override
class A { private int z; // เป็นการ Override methods ของ Super Class ชื่อ Object เป็น Built-in ของ Java @Override public String toString() { z = 5; return "result: " + z; } } // สร้าง Object A a = new A(); System.out.println(a.toString()); System.out.println(a);

Protected vs Private

  • ถ้า Parent class มีการเข้าถึงแบบ private, class ลูกจะไม่สามารถใช้ได้
  • แต่ถ้าเป็น protected หรือ public, class ลูกจะสามารถใช้ได้

super

  • super() คือ Contructor ที่มาจาก Super class
  • Constructor Chaining: คือการเรียก Constructor จากหลายๆ Class
    • เวลา extends มันจะแอบใส่ super() ของ Class แม่เข้ามาให้ก่อน (โดยอัตโนมัติ)
Constructor Chaining
public class Faculty extends Employee { public static void main(String[] args) { new Faculty(); } public Faculty() { System.out.println("(4) Faculty's no-arg constructor is invoked"); } } class Employee extends Person { public Employee() { this("(2) Invoke Employee's overloaded constructor"); System.out.println("(3) Employee's no-arg constructor is invoked"); } public Employee(String s) { System.out.println(s); } } class Person { public Person() { System.out.println("(1) Person's no-arg constructor is invoked"); } }
  • จะไม่สามารถใช้ Point(x, y) ใน Point3D ได้
class Point { private int x; private int y; Point(int x, int y) { this.x = x; this.y = y; } } class Point3D extends Point { private int z; Point3D(int x, int y, int z) { super(x, y); this.z = z; } }
  • Code นี้จะ error เพราะ Java จะใส่ super() มาใหแต่ Class Fruit ดันไม่มี Default Constructur ต้องแก้เป็นเพิ่ม public Fruit() {}
public class Apple extends Fruit { // ... // Java จะสร้างสิ่งนี้ให้ // public Apple() { // super(); // } } class Fruit { // ไม่มี Default Constructor เพราะถ้าสร้าง Constructor แบบอื่นไปแล้ว public Fruit(String name) { System.out.println("Fruit's constructor is invoked"); } }
  • นอกจาก super จะเป็น Constructor super ยังสามารถเรียก Attribute และ Methods ได้เหมือนกัน
public void printCircle() { System.out.println("The circle is created " + // super.getDateCreated() คือ Methods จาก Class แม่ super.getDateCreated() + " and the radius is " + radius); }

Overloading

void f() {} void f(int x) {} void f(double x) {}

Overriding

จะไม่สามารถทำให้ Visibility น้อยลงได้

แม่ protected -> ลูก default, protected private -> private public -> public

From,To\dArr \text{From}, \text{To} \rArrPublicProtectedDefaultPrivate
Public
Protected
Default
Private

Shadowing

  • เมื่อมีตัวแปรชื่อเหมือนกัน ตัวแปรที่ใกล้ที่สุดจะโดนเรียกก่อน แล้วตัวแปรที่สูงกว่านั้นจะถูก shadowed
public class ShadowApp { static int x; public static void main(String[] args) { x = 5; // Class System.out.println("x = " + x); // Class int x; // Local x = 10; // Local System.out.println("x = " + x); // Local System.out.println("ShadowApp.x = " + ShadowApp.x); // Class } }
  • ถ้า Inherite มาจะเรียกว่าเป็นตัวแปร Inherited scope
Scope

Week 11 Polymorphism

Polymorphism

  • ตัวแปร 1 ตัวมีการประกาศและมีตัวแปรประเภทได้มากกว่า 1 ชนิด

    // Super type class Animal { } // Sub type class Cat extends Animal { } class Dog extends Animal { } // ปกติ: Super -> Super Animal a = new Animal(); Cat c = new Cat(); Dog d = new Dog(); // Polymorphism: Super -> Sub Animal a = new Cat(); a = new Dog(); // ❌: Sub -> Super // สัตว์ ทุกตัวไม่ใช่ แมว! Cat c = new Animal();

Static Binding & Dynamic Binding

  • Static binding: คือการเช็คว่า Class นั้นมี methods นี้ไหม (Compile)

  • Dynamic binding: คือการเช็ค / เลือกว่า methods นั้นจาก Object นั้นจะไปรันของ Class ไหน (Runtime)

  • Generic Programming: คือการประกาศรับ Class ให้มันกว้างๆ ไว้ก่อน

    // Polymorphism m(new GraduateStudent()); m(new Student()); m(new Person()); m(new Object()); // Generic Programming public static void m(Object x) { // 1. Static binding // 2. Dynamic binding System.out.println(x.toString()); }

instanceof

  • เมื่อทำการเขียน Function แบบ Generic Programming แล้วต้องการใช้ methods ใน Sub Class จะไม่ผ่านตอน Static binding เนื่องจาก Super Class ไม่มี

  • ถ้าหาก Casting มาจะไม่ผิด Compile (Static binding) แต่เมื่อเรียกใช้ methods ที่อยู่ใน Sub Class, java จะทำการ Dynamic binding เพื่อไปเช็คว่า Class ของ Object นั้นๆ มี methods ไหม ซึ่งอาจจะไม่มี

  • จึงสามารถเช็คประเภทของ Object ได้ตรงๆ โดยการใช้ instaceof

    public static void m(Object x) { if(x instanceof Student) { ((Student) x).study(); } else { System.out.println("Not a student!"); } }

Object methods

  • toString(): เลข Reference ของ Object
  • equals(): เช็คว่าตำแหน่งเดียวกันไหม

Week 12 Abstract

Abstract Class & Abstract Methods

  • Abstract ช่วยให้เขียน Code ให้ Safe มากขึ้นจากการให้บังคับ Implements methods ให้ครบทุกอัน

    • เช่น หากมี Class แม่ และ ลูก Inherite อาจจะลืม implement methods จากแม่ และทำให้ผลลัพท์ผิดพลาด
    // จะไม่สามารถนำ Abstract class มาสร้าง Object ได้ // แต่ถ้าทำ Polymoriphm จาก Geometrics ได้ Geometrics obj = new Circle(); // base class abstract class Geometrics { int w, h; int r; double area, perimeter; // methods ไม่สมบูรณ์ abstract double calArea(); abstract double calPerimeter(); } // subclass class Circle extends Geometrics { // implements @Override double calArea() { // ... } @Override double calPerimeter() { // ... } }
UML Abstract

สัญลักษณ์จะเป็นตัวเอียง

กฏ(s)

  1. ถ้ามี Abstract methods, class จะต้องเป็น Abstract class ด้วย

  2. Abstract class จะไม่สามารถนำไปสร้าง Object ได้

  3. Abstract class สามารถมี methods ธรรมดาได้ จะเรียกว่า Concrete methods

    abstract class A { // Concrete methods void R() {} }
  4. เมื่อแม่เป็น Class ปกติที่มี Methods เปล่าๆ จะเรียกว่า Concrete class

    // Concrete class class A { void f() { // ... } } abstract class B extends A { abstract void f(); }
  5. สามารถใช้ Abstract class เป็น Type ได้

    GeometricsObject[] geo = new GeometricsObject[10];

Interface

  • มีลักษณะคล้าย Class แต่จะมีแค่
    • Constants
    • Abstract methods
  • สร้างมากำหนด Behavior ให้ Object
// Superclass class Person { void eat() {} void walk() {} void sleep() {} void study() {} } interface Flyable { // constant, cannot change in implemented class int flySpeed = 10; // abstract methods void fly(); } interface Fightable { // abstract methods void fight(); } class SpiderMan extends Person implements Flyable, Fightable { public void fly() { // bro cannot fly } public void fight() { // bro can fight } } class Plane implements Flyable { public void fly() { // bro can fly } } class FightPlane extends Plane implements Fightable { public void fight() { // boooomm! } }

interface สามารถ Multiple inherit ได้

interface inf0 { void a(); } interface inf1 { void f(); } interface inf2 extends inf0, inf1 { void g(); } // ต้อง Implements ให้ครบ! class A implements inf2 { public void a() {} public void f() {} public void g() {} }

Week 13 GUI

Interface 2

  • ทุกๆ Interface attribute จะมีการใส่ public final static ให้อัตโนมัติ และทุกๆ Interface methods จะมีการใส่ public abstract ให้อัตโนมัติ

Built in interface

  • Comparable

    package java.lang; public interface Comparable { public int compareTo(Object o); }
    public class Sting extends Object implements Comparable { public int compareTo(Object o) { // ... } } new String() instanceof String new String() instanceof Comparable // เช่นใน Math.max จะรับเป็น Comparable public class Max { public static Comparable max(Comparable o1, Comparable o2) { if (o1.compareTo(o2) > 0) return o1; return o2; } } String s = (String) Math.max("abc", "abcde");
  • Cloneable: Copy object ด้วย clone()

package java.lang; public interface Cloneable { } // เช่น Calendar Calendar cal = new GregorianCalendar(2003, 2, 1); Caldendar cal2 = (Calendar) cal.clone();

Shallow vs Deep copy

  • Shallow copy: จะอ้างอิงตำแหน่งเดิม

    House house1 = new House(1, 1750.50); House house2 = house1;
  • Deep copy: จะสร้างข้อมูลเหมือนกันทั้งหมด ในตำแหน่งใหม่

    House house1 = new House(1, 1750.50); House house2 = (House) house1.clone();

Interface vs Abstract class

VariablesConstructorsMethods
Abstract classได้หมดมี Constructors แต่ไม่สามารถเอาไปสร้าง Object ได้เป็นได้ทั้ง Abstract หรือ ปกติก็ได้
Interfaceได้เฉพาะต่าคงที่ไม่มี Constructors และนำไปสร้าง Object ไม่ได้ได้เฉพาะ Abstract methods

Graphics User Interface

awt and swing

Class ที่สำคัญ

Week 14 Event driven

Event

  • เหตุการณ์ ที่เกิดขึ้นในขณะรันโปรแกรม
  • เช่น
    • เลื่อนเมาส์ จะเกิด MouseEvent
    • กดปุ่ม จะเกิด ActionEvent
    • การพิมพ์ข้อควาใน TextField จะเกิด KeyEvent
  • องค์ประกอบของ Event
    • Event: Object ที่เกิดขึ้นตามประเภทของเหตุการณ์
    • Event source: ตัวที่ทำให้เกิดเหคุการณ์นั้น
    • Event handler: Object ที่ทำหน้าที่จัดการกับเหตุการณ์ผ่าน Methods ของ Event นั้นๆ เช่น Listern ต่างๆ
User actionSource ObjectEvent Type Generate
Click a buttonJButtonActionEvent
Click a check boxJCheckBoxItemEvent, ActionEvent
Click a radio buttonJRadioButtonItemEvent, ActionEvent
Pree return on a text fieldJTextFieldActionEvent
Select a new itemJComboBoxItemEvent, ActionEvent
Window opened, closed, etc.WindowWindowEvent
Mouse pressed, released, etc.ComponentMouseEvent
Key released, presseed, etc.ComponentKeyEvent

Listener interface

  • เป็น Interface ที่คอยรับฟังเหตุการณ์
  • การลงทะเบียนรับ Event กับ Components
InterfaceMethod to listen to event
ActionListeneraddActionListener()
ItemListeneraddItemListener()
KeyListeneraddKeyListener()
MouseListeneraddMouseListener()
......
  • จะต้องมี Methods ที่ต้อง override เมื่อจะจัดการกับ Event
Event ClassListener InterfaceListener Methods (Handlers)
ActionEventActionListeneractionPerformed(ActionEvent)
ItemEventItemListeneritemStateChanged(ItemEvent)
WindowEventWindowListenerwindowClosing(WindowEvent)
(ต้อง Override ให้ครบทั้ง 7)windowOpened(WindowEvent)
windowIconified(WindowEvent
windowDeiconified(WindowEvent)
windowClosed(WindowEvent)
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
.........
class Listener implements ActionListener { public void actionPerformed(ActionEvent e) { // ... } }

วิธีการสร้าง Listener

  1. สร้าง Inner Class

    class Ex extends JFrame { // Inner class class Listener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // ... } } }
  2. สร้าง Anonymous Listener

    class Ex extends JFrame { ex() { // Anonymous Listener addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // ... } }) } }
  3. สร้าง External Class

    class Ex extends JFrame { ex() { addActionListener(new Listener()); } } // External class class Listener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // ... } }
  4. รวมกับ Component ด้วย implements Listener

    class Ex extends JFrame implements ActionListener { public void actionPerformed(ActionEvent e) { // ... } }

Week 15 Threads

1 Process จะรันได้หลาย Threads แต่จะไม่ใช่การ run แบบ Parallel แต่จะสามารถแบ่งช่วงเวลาเล็กๆ ได้

class ThreadNum implements Runnable { public void run() { System.out.println("Thread is running..."); } } Thread t1; t1 = new Thread(new ThreadNum()); t1.start();
class ThreadNum extends Thread { public void run() { System.out.println("Thread is running..."); } } ThreadNum t1; t1 = new ThreadNum(); t1.start();

sleep, suspend, resume

  • sleep(ms): เป็นการเปลี่ยน Threads เป็น Blocked แต่จะกลับมา Running เมื่อผ่านไป ms

  • suspend(): เป็นการเปลี่ยน Threads เป็น Blocked

  • resume(): เป็นการเปลี่ยน Threads เป็น Running

    try { Thread.sleep(200); } catch(InterruptedException e) {}

wait, notify

  • wait(): ให้ Thread หยุด
  • notify(): ประกาศว่าพร้อมที่จะทำงานต่อได้แล้ว (ให้ Thraed ทำต่อ)