Object-Oriented Programming เนื้อหาไฟนอล 2023/1
September 6, 2023
- แนวข้อสอบ
- Week 10 Inheritance
- Week 11 Polymorphism
- Week 12 Abstract
- Week 13 GUI
- Week 14 Event driven
- Week 15 Threads
- wait, notify
แนวข้อสอบ
มี 3 ตอน เก็บ 40% 87 คะแนน
- ตอนที่ 1 (40 คะแนน)
- หาผลลัพท์โปรแกรม
- Inheritance / Polymophism / Static Binding / Dynamic Binding
- ตอบคำถามเรื่อง
- Inheritance + implements คราส Interface
- เขียนโปรแกรม Interface
- ตอบคำถามถูกผิดเกี่ยวกับ ... + interface
- เขียนโปรแกรม Dynamic Binding
- หาผลลัทธ์ Graphics
- หาผลลัพท์โปรแกรม
- ตอนที่ 2 เขียนโปรแกรม GUI + Event 2 ข้อ 20 คะแนน
- ตอนที่ 3 เขียนโปรแกรม Algorithm 2 ข้อ 15 คะแนน
Week 10 Inheritance
OOP Concept
- Abstraction: มองทุกอย่างเป็น Class และ object
- Encapsulation: การป้องกันข้อมูล
- Public
- Private
- Protected
- Inheritance: การสืบทอดคุณสมบัติ
- 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() {} }
โดยปกติแล้ว 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 แม่เข้ามาให้ก่อน (โดยอัตโนมัติ)
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
Public | Protected | Default | Private | |
---|---|---|---|---|
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
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() { // ... } }
สัญลักษณ์จะเป็นตัวเอียง
กฏ(s)
-
ถ้ามี Abstract methods, class จะต้องเป็น Abstract class ด้วย
-
Abstract class จะไม่สามารถนำไปสร้าง Object ได้
-
Abstract class สามารถมี methods ธรรมดาได้ จะเรียกว่า Concrete methods
abstract class A { // Concrete methods void R() {} }
-
เมื่อแม่เป็น Class ปกติที่มี Methods เปล่าๆ จะเรียกว่า Concrete class
// Concrete class class A { void f() { // ... } } abstract class B extends A { abstract void f(); }
-
สามารถใช้ 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
Variables | Constructors | Methods | |
---|---|---|---|
Abstract class | ได้หมด | มี Constructors แต่ไม่สามารถเอาไปสร้าง Object ได้ | เป็นได้ทั้ง Abstract หรือ ปกติก็ได้ |
Interface | ได้เฉพาะต่าคงที่ | ไม่มี Constructors และนำไปสร้าง Object ไม่ได้ | ได้เฉพาะ Abstract methods |
Graphics User Interface
- awt (Abstract Window Toolkit)
- swing
- หน้าจอเหมือนกันทุก OS
- import javax.swing.*;: javax = java extend
- JFrame, JPanel, JButton, JLabel, JTextField, ...
- Java 2D
- Accessibility
- Drag and Drop
awt and swing
Class ที่สำคัญ
- Component
- Container
- LayoutManager
- Graphics
- Color
- Font
Week 14 Event driven
Event
- เหตุการณ์ ที่เกิดขึ้นในขณะรันโปรแกรม
- เช่น
- เลื่อนเมาส์ จะเกิด MouseEvent
- กดปุ่ม จะเกิด ActionEvent
- การพิมพ์ข้อควาใน TextField จะเกิด KeyEvent
- องค์ประกอบของ Event
- Event: Object ที่เกิดขึ้นตามประเภทของเหตุการณ์
- Event source: ตัวที่ทำให้เกิดเหคุการณ์นั้น
- Event handler: Object ที่ทำหน้าที่จัดการกับเหตุการณ์ผ่าน Methods ของ Event นั้นๆ เช่น Listern ต่างๆ
User action | Source Object | Event Type Generate |
---|---|---|
Click a button | JButton | ActionEvent |
Click a check box | JCheckBox | ItemEvent, ActionEvent |
Click a radio button | JRadioButton | ItemEvent, ActionEvent |
Pree return on a text field | JTextField | ActionEvent |
Select a new item | JComboBox | ItemEvent, ActionEvent |
Window opened, closed, etc. | Window | WindowEvent |
Mouse pressed, released, etc. | Component | MouseEvent |
Key released, presseed, etc. | Component | KeyEvent |
Listener interface
- เป็น Interface ที่คอยรับฟังเหตุการณ์
- การลงทะเบียนรับ Event กับ Components
Interface | Method to listen to event |
---|---|
ActionListener | addActionListener() |
ItemListener | addItemListener() |
KeyListener | addKeyListener() |
MouseListener | addMouseListener() |
... | ... |
- จะต้องมี Methods ที่ต้อง override เมื่อจะจัดการกับ Event
Event Class | Listener Interface | Listener Methods (Handlers) |
---|---|---|
ActionEvent | ActionListener | actionPerformed(ActionEvent) |
ItemEvent | ItemListener | itemStateChanged(ItemEvent) |
WindowEvent | WindowListener | windowClosing(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
-
สร้าง Inner Class
class Ex extends JFrame { // Inner class class Listener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // ... } } }
-
สร้าง Anonymous Listener
class Ex extends JFrame { ex() { // Anonymous Listener addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // ... } }) } }
-
สร้าง External Class
class Ex extends JFrame { ex() { addActionListener(new Listener()); } } // External class class Listener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // ... } }
-
รวมกับ 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
-
resume(): เป็นการเปลี่ยน Threads เป็น Running
try { Thread.sleep(200); } catch(InterruptedException e) {}