550 likes | 668 Views
Lec05 :: การสืบทอด ( inheritance). โดย อ. นัฐพงศ์ ส่งเนียม http://www.siam2dev.com xnattapong@hotmail.com. หัวข้อ. การสืบทอด การเข้าใช้แบบ protected พอลิมอร์ฟิซึม การสืบทอดในภาษาจาวา คลาส Object. การสืบทอด. สัตว์ต่างๆ. คลาสแมว แอตทริบิวต์ ได้แก่ อายุ และ ความหิว
E N D
Lec05 :: การสืบทอด (inheritance) โดย อ. นัฐพงศ์ ส่งเนียม http://www.siam2dev.com xnattapong@hotmail.com
หัวข้อ • การสืบทอด • การเข้าใช้แบบ protected • พอลิมอร์ฟิซึม • การสืบทอดในภาษาจาวา • คลาส Object
สัตว์ต่างๆ • คลาสแมว • แอตทริบิวต์ ได้แก่ อายุ และ ความหิว • เมธอด ได้แก่ กิน() และ นอน() • คลาสปลา • แอตทริบิวต์ ได้แก่ อายุ ความหิว และชื่อ (เช่น ปลานีโม) • เมธอด ได้แก่ กิน() และ นอน() • คลาสลิง • แอตทริบิวต์ ได้แก่ อายุ และ ความหิว • เมธอดได้แก่ กิน() นอน() และเก็บลูกมะพร้าว()
แอททริบิวท์และเมธอดที่คล้ายกันแอททริบิวท์และเมธอดที่คล้ายกัน
การสืบทอด • แก้ปัญหาการเขียนโปรแกรมซ้ำซ้อนกันได้ • เมธอดหรือแอตทริบิวต์ที่คลาสต่างๆ มีร่วมกันจะถูกนำไปใส่ในคลาสแม่ • คลาสลูกจะสืบทอดเมธอดและแอตทริบิวต์คลาสแม่โดยอัตโนมัติ
การทดสอบการสืบทอด • แต่งประโยคโดยใช้คำว่า “เป็น” เข้าช่วย • ลิงเป็นสัตว์ • สัตว์เป็นลิง • ลิงไซบอร์ก เป็น ลิงและหุ่นยนต์ • รถยนต์เป็นพาหนะ • เครื่องยนต์เป็นรถยนต์
คลาสสัตว์ • แมว ปลา และลิง เป็นสัตว์ สัตว์ทุกตัวสามารถกินและนอนได้ เราจึงนำแอตทริบิวต์และเมธอดที่สัตว์ต่างๆมีร่วมกัน ไปใส่ในคลาสสัตว์ class สัตว์ { // แอตทริบิวต์ อายุ; ความหิว; // เมธอด กิน() {… } นอน() {… } }
การสืบทอด • รูปแบบ • classคลาสลูกextendsคลาสแม่ • ตัวอย่าง class แมว extends สัตว์ { } class ปลา extends สัตว์ { } class ลิง extends สัตว์ { }
วัตถุในคลาสลูกสามารถทำงานตามเมธอดของคลาสแม่ได้วัตถุในคลาสลูกสามารถทำงานตามเมธอดของคลาสแม่ได้ ลิง ล = new ลิง(); ล.กิน();
เพิ่มเมธอดในคลาสลูก class ลิง extends สัตว์ { // เมธอดที่เพิ่มเข้ามา เก็บลูกมะพร้าว() { … } } ลิง ล = new ลิง(); ล.เก็บลูกมะพร้าว(); สัตว์ ส = new สัตว์(); ส.เก็บลูกมะพร้าว();
เพิ่มแอททริบิวท์ในคลาสลูกเพิ่มแอททริบิวท์ในคลาสลูก class ปลา extends สัตว์ { // แอตทริบิวต์ที่เพิ่มเข้ามา ชื่อ; }
การโอเวอร์ไรด์เมธอด class ปลา extends สัตว์ { // แอตทริบิวต์ ชื่อ; // เมธอด นอน() { // วิธีการนอนของปลา … } }
ความหมาย • poly แปลว่าหลายหรือมาก • morphism นั้นมาจากคำว่า morph ซึ่งแปลว่ารูปร่าง • รวมกันแล้วหมายถึงความสามารถที่สิ่งหนึ่งจะมีได้หลายรูปร่าง ซึ่งเมื่อใช้คำนี้กับการโปรแกรมเชิงวัตถุ ก็จะหมายถึงการที่คำสั่งแบบเดียวกันสามารถถูกแปลได้หลายแบบ
พอลิมอร์ฟิซึมกับการนำกลับมาใช้ใหม่ • พอลิมอร์ฟิซึมสนับสนุน การนำกลับมาใช้ใหม่(reuse) • ถ้าเราได้เขียนโปรแกรมที่ใช้งานได้กับสัตว์ โปรแกรมของเราย่อมใช้ได้กับแมว ปลา และลิงนอกจากนั้นถ้ามีคนสร้างคลาสอีกัวน่าขึ้นมาใหม่ โปรแกรมที่เราเขียนก็สามารถใช้ได้กับคลาสอีกัวน่าเช่นกัน
คลาสรูปร่างและคลาสที่สืบทอดคลาสรูปร่างและคลาสที่สืบทอด
คลาสรูปร่าง • รูปร่างเป็นรูปที่อยู่ในระนาบสองมิติ • มีพื้นที่ • เมธอด getArea() ใช้คำนวณหาพื้นที่ของรูปร่าง • มีสี • public enum Color { Red, Green, Blue } • เมธอด getColor()
คลาสรูปร่าง public class Shape { public Shape() { color = Color.Red; } public double getArea() { return 0; } public void setColor(Color c) { color = c; } public Color getColor() { return color; } private Color color; }
ทดสอบคลาสรูปร่าง public class TestShape { public static void main(String[] args) { Shape s1 = new Shape(); System.out.println(s1.getColor()); System.out.println(s1.getArea()); Shape s2 = new Shape(); s2.setColor(Color.Blue); System.out.println(s2.getColor()); System.out.println(s2.getArea()); } }
คลาสสี่เหลี่ยมผืนผ้า class Rectangle extends Shape{ ... public double getArea() { return width * height; } }
เมธอด toString() public class Rectangle extends Shape { ... public String toString() { String str = "Rectangle"; str += " color=" + getColor(); str += " width=" + width; str += " height=" + height; str += " area=" + getArea(); return str; } }
เมธอด toString() • เป็นเมธอดที่ถูกโอเวอร์ไรด์จากคลาส Object
คลาส Object • แม่ของทุกคลาส • เมธอดที่น่าสนใจ • toString() • equals() • clone() • hashCode()
เมธอด equals() public boolean equals(Object otherObject) { if (otherObject instanceof Rectangle) { Rectangle otherRect = (Rectangle) otherObject; boolean equalWidth = width == otherRect.width; boolean equalHeight = height == otherRect.height; return equalWidth && equalHeight; } return false; }
เมธอด hashCode() • จะส่งจำนวนเต็มที่เป็นรหัสแฮช เพื่อการค้นหาข้อมูลที่รวดเร็ว public int hashCode() { return (int) (width + height * 17); }
เมธอด clone() สร้างวัตถุที่เหมือนกับวัตถุที่ได้รับข้อความ public Object clone() { Rectangle clone = new Rectangle(width, height); return clone; }
ทดสอบเมธอดที่โอเวอร์ไรด์จากคลาส Object public class TestRectangle3 { public static void main(String[] args) { Rectangle r1 = new Rectangle(2, 5); System.out.println(r1); System.out.println(r1.hashCode()); Rectangle r2 = new Rectangle(5, 2); System.out.println(r1.equals(r2)); Rectangle r3 = (Rectangle) r1.clone(); System.out.println(r1.equals(r3)); } }
สรุปเมธอดในคลาสสี่เหลี่ยมผืนผ้าสรุปเมธอดในคลาสสี่เหลี่ยมผืนผ้า
คลาสสี่เหลี่ยมจัตุรัสคลาสสี่เหลี่ยมจัตุรัส public class Square extends Rectangle { public Square( double w) { super(w,w); } ... }
ไฟนอลคลาส • ไม่สามารถถูกสืบทอดได้ public final class Square
ไฟนอลเมธอด • ไม่สามารถถูกโอเวอร์ไรด์ได้ public class Shape { public final Color getColor() { return color; } ... }
การเข้าใช้แบบ protected • คลาสลูกสามารถใช้เมธอดและแอททริบิวท์ที่มีการเข้าใช้แบบ protectedได้ • คลาสที่อยู่ในแพ็คเกจเดียวกันก็สามารถใช้เมธอดและแอททริบิวท์ที่มีการเข้าใช้แบบ protected ได้ • การเข้าใช้แบบนี้มีความเข้มงวดน้อยกว่าแบบprivate ซึ่งห้ามคลาสอื่นใดเข้าใช้ แต่ก็อิสระน้อยกว่าแบบpublic ที่ใครๆก็สามารถเข้าใช้ได้
คลาสวงกลม public class Circle extends Shape { protected double radius; public Circle(double r) { radius = r; } public double getRadius() { return radius; } ... }
คำนวณพื้นที่ของวงแหวนคำนวณพื้นที่ของวงแหวน public class Ring1 extends Circle { public double getArea() { double outerArea = Math.PI * radius * radius; double innerArea = Math.PI * innerRadius * innerRadius; return outerArea - innerArea; } ... }
คำนวณพื้นที่ของวงแหวนคำนวณพื้นที่ของวงแหวน public class Ring2 extends Circle { public double getArea() { double outerArea = super.getArea(); double innerArea = Math.PI * innerRadius * innerRadius; return outerArea - innerArea; } ... }
คลาสที่ประกาศขึ้นมาลอยๆ (AbstractClass) • เมธอด getArea() ในคลาส Shape ไม่ควรส่งค่าศูนย์หรือค่าใดๆกลับมา ทั้งนี้เพราะว่าเราไม่ทราบวิธีคำนวณหาพื้นที่ของวัตถุ Shape public abstractdouble getArea(); • เมธอดที่ถูกประกาศขึ้นมาลอยๆ (abstract) นี้ต้องอยู่ในคลาสที่เป็น abstract ด้วยเช่นกัน คลาส Shape เขียนใหม่ได้ดังนี้ public abstract class Shape { public abstract double getArea(); ... }
การใช้งาน abstract class • ไม่สามารถสร้างวัตถุในคลาสนี้ได้ Shape s = new Shape(); • แต่อ้างถึงวัตถุในคลาสลูกได้ Shape s; s = new Rectangle(3,2); s = new Square(5);
พอลิมอร์ฟิซึม public class TestPolymorphism { public static void main(String[] args) { Shape shape; shape = new Rectangle(10, 20); System.out.println(shape.getArea()); shape = new Circle(10); System.out.println(shape.getArea()); } }
การนำมาใช้อีก public class ShapeArray { public static double sumArea(Shape[] shapes) { double sum = 0; for( Shape s : shapes) { sum += s.getArea(); } return sum; } }
การนำมาใช้อีก Shape[] s = new Shape[3]; s[0] = new Triangle(10); s[1] = new Rectangle(10,20); s[2] = new Pentagon(20); double d = ShapeArray.sumArea(s);
ข้อดีข้อเสียของการสืบทอดข้อดีข้อเสียของการสืบทอด