ในการเขียนโปรแกรมเชิงวัตถุเราจะออกแบบคลาสโดยอ้างอิงหลักการต่างๆ ประกอบด้วย คุณสมบัติการห่อหุ้ม(encapsulation)  คุณสมบัติการสืบทอด(inheritance)  คุณสมบัติความหลากหลายรูปแบบ(polymorphism) และคุณสมบัติการประกาศรูปแบบ(abstraction) 

คุณสมบัติการห่อหุ้ม (Encapsulation) ของคลาส

     คุณสมบัติการห่อหุ้ม (encapsulation) ของคลาสเป็นหลักการหนึ่งของการเขียนโปรแกรมเชิงวัตถุ คุณสมบัติการห่อหุ้มถูกใช้เพื่อทำให้ข้อมูลภายในออบเจกต์ถูกปกป้องจากการเข้าถึงโดยตรง โดยเป็นการกำหนดความสามารถในการเข้าถึงฟิลด์และเมธอดของคลาสจากภายนอกคลาสและกำหนดการเรียกใช้งานออบเจกต์อย่างชัดเจน การสร้างคลาสโดยยึดหลักคุณสมบัติการห่อหุ้มทำให้ออบเจกต์มีความน่าเชื่อถือว่าจะทำงานได้ตามที่ออกแบบไว้เสมอโดยปราศจากการแทรกแซงจากภายนอก และโปรแกรมอื่นที่เรียกใช้งานออบเจกต์นี้จะไม่ได้รับผลกระทบจากการปรับปรุงคลาสในภายหลัง

     คุณสมบัติการห่อหุ้มเป็นแนวคิดที่ได้มาจากในชีวิตจริง โดยในการเขียนโปรแกรมเชิงวัตถุเรามองทุกอย่างเป็นเหมือนออบเจกต์ในโลกจริง ยกตัวอย่างเช่น เมื่อเราต้องการซื้อตั๋วรถไฟฟ้าที่เครื่องจำหน่ายตั๋วอัตโนมัติ เราจะต้องใส่เงินเข้าไปในเครื่องจำหน่ายตั๋วและเครื่องจะส่งตั๋วให้กับเรา แต่เราจะไม่ทราบว่าเครื่องจำหน่ายตั๋วทำงานอย่างไรตั้งแต่รับเงินเราเข้าไปจนกระทั่งส่งตั๋วออกมาให้เรา เรียกได้ว่าการทำงานที่จะให้ได้ตั๋วมานั้นถูกปกปิด เราไม่จำเป็นจะต้องทราบว่าเครื่องจำหน่ายตั๋วทำงานอย่างไร แต่สิ่งที่เราจะต้องรู้คือการใช้งานเพื่อที่จะซื้อตั๋วเท่านั้น ด้วยหลักการเดียวกันใครที่จะมาใช้งานคลาสของเราก็ไม่จำเป็นต้องรู้ว่าภายในคลาสเราทำงานอย่างไร รู้แค่ว่าจะใช้งานอย่างไรและได้ผลลัพธ์ออกมาเป็นอะไรเท่านั้น

     ในภาษาจาวาเราใช้คีย์เวิร์ดควบคุมการเข้าถึง (access modifier)ในการควบคุมความสามารถในการเข้าถึงฟิลด์และเมธอด โดยเราจะกำกับด้วยคีย์เวิร์ด private เพื่อป้องกันไม่ให้ฟิลด์และเมธอดถูกใช้งานจากภายนอกคลาส และเราจะกำกับด้วยคีย์เวิร์ด public ให้กับเมธอดที่เรากำหนดให้เป็นจุดเชื่อมต่อกับภายนอกคลาส ซึ่งในเมธอดดังกล่าวมักจะมีการตรวจสอบเงื่อนไขการใช้งานเพื่อป้องกันข้อผิดพลาดที่อาจจะเกิดขึ้น

     การกำกับด้วยคีย์เวิร์ด private ให้กับฟิลด์และเมธอดเปรียบเหมือนกับการที่เรามองไม่เห็นกลไกการทำงานในเครื่องจำหน่ายตั๋วอัตโนมัติ  ส่วนการกำหนดคีย์เวิร์ด public ให้กับเมธอดเปรียบเหมือนกับการมีช่องรับเงินและปุ่มกดสำหรับซื้อตั๋วที่อยู่หน้าเครื่อง คุณสมบัติการห่อหุ้มทำให้ออบเจกต์เป็นอิสระจากกัน และหากในภายหลังเราต้องการแก้ไขคลาส เช่น เปลี่ยนแปลงชื่อฟิลด์หรือแก้ไขรูปแบบการทำงานในเมธอดโดยที่ชื่อเมธอดกับพารามิเตอร์ที่เป็นส่วนเชื่อมต่อยังเหมือนเดิมก็จะไม่กระทบกับโปรแกรมอื่นที่เรียกใช้งานโปรแกรมของเรา 

    ในการทำความเข้าใจให้นึกเสมอว่าในการใช้งานภาษาจาวา คลาสเป็นแผนผังในการสร้างออบเจกต์ และสิ่งที่เราใช้งานจริงๆคือออบเจกต์ที่สร้างขึ้นมา ดังนั้นผลลัพธ์ของคุณสมบัติการห่อหุ้มคือออบเจกต์ที่มีวิธีการเรียกใช้งานที่ชัดเจนแต่ไม่เปิดเผยวิธีการทำงานภายในของมัน

การกำหนดคีย์เวิร์ดควบคุมการเข้าถึงในคลาส

     การกำกับด้วยคีย์เวิร์ดควบคุมการเข้าถึง (access modifier) สำหรับคลาสและส่วนต่างๆภายในคลาสจะช่วยให้เราออกแบบคลาสตามคุณสมบัติการห่อหุ้ม (encapsulation) ซึ่งเป็นหลักการสำคัญอย่างหนึ่งในการเขียนโปรแกรมเชิงวัตถุ 

     จากตัวอย่างจะเห็นการกำกับด้วยคีย์เวิร์ด public ที่บรรทัด public class Account เพื่อประกาศว่าคลาส Account สามารถถูกเรียกใช้งานจากคลาสอื่นได้ และยังมีการกำกับด้วยคีย์เวิร์ด public กับบรรทัด public void deposit ..  และบรรทัด public void widthdrawal … เพื่อประกาศว่าทั้งสองเมธอดสามารถถูกเรียกใช้งานจากคลาสอื่นได้เช่นกัน แต่ในบรรทัดเช่น private String number จะเป็นการประกาศว่าฟิลด์นี้ถูกเข้าถึงข้อมูลได้จากภายในคลาสตนเองเท่านั้น คลาสอื่นจะมองไม่เห็นฟิลด์นี้หรือมองอีกมุมหนึ่งคือเราซ่อนฟิลด์นี้จากการมองเห็นของคลาสอื่นนั่นเอง ดังนั้นโปรแกรมหรือคลาสอื่นสามารถเรียกใช้งานคลาส Account ผ่านทางเมธอดที่เรากำหนดเป็น  public หรือเรียกว่าเป็นส่วนเชื่อมต่อ (API) ของคลาส Account ซึ่งก็คือเมธอด deposit และ widthdrawal เท่านั้น

คุณสมบัติการสืบทอด (inheritance) ของคลาส

     จากที่เราทราบว่าคลาสคือตัวแบบหรือพิมพ์เขียวในการสร้างออบเจกต์ ในกรณีที่เราต้องการสร้างออบเจกต์ในกลุ่มเดียวกันที่มีฟิลด์และเมธอดส่วนใหญ่เหมือนกัน แต่มีบางฟิลด์และบางเมธอดต่างกัน เราสามารถสร้างคลาสที่มีเฉพาะฟิลด์และเมธอดที่เหมือนกัน และสร้างคลาสอีกคลาสหนึ่งที่จะสืบทอดฟิลด์และเมธอดจากคลาสแรกมาใช้งานและเพิ่มฟิลด์และเมธอดที่แตกต่างเข้าไป เราจะเรียกคลาสที่เป็นต้นฉบับว่าคลาสแม่ (super class หรือ parent class) และเรียกคลาสที่สืบทอดมาว่าคลาสลูก (sub class หรือ child class) คุณสมบัติการสืบทอดช่วยประหยัดเวลาในการเขียนโปรแกรมและส่งเสริมการนำโค๊ดกลับมาใช้ใหม่ เช่น หากเราต้องการสร้างคลาสใหม่ขึ้นมาและหากเรามีคลาสที่มีเมธอดหรือฟิลด์ที่เราต้องการอยู่แล้ว เราสามารถสืบทอดคลาสดังกล่าวแล้วเพิ่มฟิลด์กับเมธอดที่เราต้องการเข้าไป

      ในการทำความเข้าใจให้แยกเรื่องคลาสออกจากออบเจกต์ อย่าสับสนว่าเรามีคลาสลูก คลาสแม่ หรือมันเป็นคนละคลาสกัน เพราะคลาสเป็นแผนผังในการสร้างออบเจกต์และคุณสมบัติการสืบทอดช่วยให้เราเขียนแผนผังได้เร็วขึ้น ดังนั้นแทนที่เราจะต้องเขียนส่วนของโปรแกรมซ้ำๆเพียงเพื่อสร้างออบเจกต์ที่มีข้อแตกต่างในบางส่วน เราใช้คุณสมบัติการสืบทอดช่วยให้เขียนโปรแกรมน้อยลง แต่สิ่งที่เราใช้งานจริงๆคือออบเจกต์ที่สร้างขึ้นมา ดังนั้นออบเจกต์ที่สร้างขึ้นมาก็คือวัตถุที่มีชนิดเดียวกันแต่แตกต่างกันที่ลักษณะบางอย่าง เช่น รถยนต์ สามารถแยกแยะได้เป็น รถสปอร์ต รถประหยัดพลังงาน รถขนาดครอบครัว เป็นต้น แต่ทั้งหมดก็คือรถยนต์ที่มีคุณสมบัติหลักๆเหมือนกัน

การสืบทอดคลาส

     การสืบทอดคลาสคือการสร้างคลาสที่กำกับด้วยคีย์เวิร์ด  extends แล้วตามด้วยชื่อคลาสที่ต้องการสืบทอด จากตัวอย่างเรามีคลาส Car และเราจะสร้างคลาส SportCar โดยสืบทอดจากคลาส Car ดังนี้

     ในประโยคคำสั่งสร้างคลาสจะเห็นว่ามีคีย์เวิร์ด extends ตามด้วยชื่อคลาส Car หมายถึงคลาส SportCar สืบทอดมาจากคลาส Car ดังนั้นคลาส Car คือคลาสแม่และคลาส SportCar คือคลาสลูก

     การสร้างเมธอดคอนสตรัคเตอร์ของคลาส SportCar ทำโดยไปที่เมนู Code > Generate และเลือก Constructor แต่จะมีขั้นตอนเพิ่มขึ้นมาให้เราเลือกคอนสตรัคเตอร์ของคลาส Car ที่ต้องการใช้ สังเกตุว่าเมธอดคอนสตรัคเตอร์ของคลาส SportCar ที่สร้างขึ้นมาจะประกอบด้วยฟิลด์ทั้งจากคลาส Car และคลาส SportCar แต่ฟิลด์จากคลาส Car จะถูกส่งกลับไปดำเนินการที่เมธอดคอนสตรัคเตอร์ของคลาส Car โดยการใช้คีย์เวิร์ด super ตามด้วยพารามิเตอร์ที่ใช้กับเมธอดคอนสตรัคเตอร์ของคลาส Car ดังนั้นออบเจกต์ที่สร้างจากคลาส SportCar จะมีฟิลด์และเมธอดของคลาส Car ด้วย จากตัวอย่างด้านล่างจะเห็นว่ามีเมธอดจากคลาส Car มาให้เลือกด้วย

     จากคุณสมบัติการสืบทอด คลาสลูกจะสามารถใช้งานฟิลด์และเมธอดของคลาสแม่ได้ ตราบเท่าที่ฟิลด์และเมธอดเหล่านั้นในคลาสแม่ไม่ได้ถูกกำกับด้วยคีย์เวิร์ดควบคุมแบบ private 

การโอเวอร์ไรด์เมธอด

     เมื่อเราสร้างคลาสที่สืบทอดมาจากคลาสอื่น ออบเจกต์ที่สร้างขึ้นมาจากคลาสลูกจะสามารถใช้เมธอดที่มีในคลาสแม่ได้ ซึ่งทำให้เราประหยัดเวลาในการเขียนโปรแกรมเพื่อสร้างคลาส แต่ในกรณีที่เราต้องการให้เมธอดดังกล่าวทำงานแตกต่างออกไปจากเดิม เราจะใช้วิธีการโอเวอร์ไรด์ (override) เมธอด

     การโอเวอร์ไรด์ (override) เมธอดคือการสร้างเมธอดในคลาสลูกที่สืบทอดมาจากคลาสแม่โดยเมธอดจะมีชื่อเมธอดและพารามิเตอร์เหมือนกันกับที่มีในคลาสแม่ แต่มีวิธีการทำงานในเมธอดแตกต่างออกไป ทั้งนี้เพื่อให้สามารถสร้างการใช้งานแบบเฉพาะเจาะจงสำหรับคลาสลูกด้วยเมธอดชื่อเดียวกันกับคลาสแม่ ตัวอย่างเช่นเรามีเมธอดชื่อ accelerate เพื่อเพิ่มความเร็วของรถในคลาส Car 

      แต่เนื่องจากคลาส SportCar คือรถสปอร์ตที่ต้องเพิ่มความเร็วได้เร็วกว่ารถปรกติ เราจึงจะโอเวอร์ไรด์เมธอด accelerate โดยไปที่เมนู Code > Generate และเลือก Override Methods …

      จากนั้นเลือกเมธอดที่ต้องการโอเวอร์ไรด์ 

     โปรแกรม IntelliJ IDEA จะสร้างเมธอดขึ้นมาให้ดังตัวอย่าง และประกาศคำอธิบายประกอบว่า @Override เพื่อบอกว่าเมธอดนี้มาจากการโอเวอร์ไรด์ ส่วนประโยคคำสั่งในเมธอดคือการเรียกใช้เมธอด accelerate จากคลาส Car เนื่องจากใช้คีย์เวิร์ด  super เพื่ออ้างอิงถึงเมธอดในคลาสแม่

     เราสามารถแก้ไขเมธอดที่โอเวอร์ไรด์มาเพื่อให้ทำงานตามที่เราต้องการได้ เช่น จากตัวอย่างด้านล่างเราเรียกใช้เมธอด accelerate ของคลาสแม่ซ้ำๆเพื่อเป็นการเพิ่มความเร็วให้มากขึ้น และเมื่อมีการเรียกใช้เมธอด accelerate จากออบเจกต์ของคลาส SportCar เมธอดที่ถูกโอเวอร์ไรด์นี้จะถูกเรียกใช้แทนที่จะเป็นเมธอด accelerate ในคลาส Car

     เมธอดโอเวอร์ไรด์มักจะถูกเรียกว่า runtime polymorphism หรือ dynamic method dispatch เพราะเมธอดที่เราโอเวอร์ไรด์จะถูกตัดสินใจเลือกใช้โดย java virtual machine ในขั้นตอนการใช้งานโปรแกรม

การใช้ this, this(), super และ super()

     จากตัวอย่างที่ผ่านมาจะเห็นการใช้คีย์เวิร์ด this และ super ในการอ้างอิงฟิลด์และเมธอด จึงนำมาสรุปเพื่อความเข้าใจที่ชัดเจนขึ้นดังนี้

     ในกรณีที่เราสร้างเมธอดที่ใช้พารามิเตอร์ในชื่อเดียวกันกับฟิลด์ในคลาสเดียวกัน เราจะอ้างอิงว่าเป็นฟิลด์ของคลาสด้วยคีย์เวิร์ด this ดังตัวอย่างด้านล่างบรรทัดที่ 39 

     ในกรณีที่เราโอเวอร์โหลดเมธอดคอนสตรัคเตอร์ เราจะเรียกใช้งานอีก

เมธอดคอนสตรัคเตอร์โดยใช้เมธอด this() ตามด้วยพารามิเตอร์ ดังตัวอย่างด้านล่างบรรทัดที่ 17 และ this() จะต้องอยู่เป็นบรรทัดแรก การใช้ this() จะช่วยลดความซ้ำซ้อนในการกำหนดค่าให้ตัวแปร ไม่เช่นนั้นเราก็จะต้องมีบรรทัดที่กำหนดค่าให้กับตัวแปรซ้ำๆกันในแต่ละเมธอดคอนสตรัคเตอร์

     ในกรณีที่เราสร้างคลาสลูกที่สืบทอดมาจากคลาสแม่ เมธอดคอนสตรัคเตอร์ในคลาสลูกจะต้องครอบคลุมฟิลด์จากทั้งคลาสแม่และคลาสลูก แต่ฟิลด์จากคลาสแม่จะถูกส่งกลับไปดำเนินการด้วยเมธอดคอนสตรัคเตอร์ในคลาสแม่ โดยใช้เมธอด super() ตามด้วยพารามิเตอร์ของเมธอดคอนสตรัคเตอร์ในคลาสแม่ ดังตัวอย่างด้านล่างบรรทัดที่ 13 โดย super() ต้องอยู่เป็นบรรทัดแรก

     ในกรณีที่เราต้องการอ้างถึงเมธอดหรือฟิลด์ในคลาสแม่จากโปรแกรมในคลาสลูก เช่น ในกรณีที่เราโอเวอร์ไรด์เมธอดแต่ยังคงใช้เมธอดในคลาสแม่นั้นเราใช้คีย์เวิร์ด super ตามด้วยชื่อเมธอดหรือชื่อฟิลด์ เช่น super.fieldname หรือ super.methodname ในกรณีที่เราโอเวอร์ไรด์เมธอดในคลาสแม่แต่ไม่กำกับด้วยคีย์เวิร์ด super จะทำให้โปรแกรมเรียกเมธอดของตัวเองเป็น recursive ไม่รู้จบ

     คีย์เวอร์ด  super และ this จะไม่ถูกใช้ในส่วนที่เป็น static ไม่เช่นนั้นจะเกิด ข้อผิดพลาดในขั้นตอนการคอมไพล์โปรแกรม และเราจะไม่ใช้เมธอด this() และ super() ด้วยกันในเมธอดคอนสตรัคเตอร์

การใช้คีย์เวอร์ด final กับคลาสและเมธอด

     ความหมายของคีย์เวิร์ด final เมื่อถูกนำไปใช้กับอะไรก็ตามคือสิ่งนั้นๆจะไม่สามารถถูกเปลี่ยนแปลงได้อีก เราใช้คีย์เวิร์ด final เมื่อเราต้องการแน่ใจว่าสิ่งที่เรากำหนดจะไม่ถูกแก้ไขให้แตกต่างไปจากที่เรากำหนดไว้ เช่น ในกรณีที่เราไม่ต้องการให้คลาสของเราถูกสืบทอด เราจะใช้การกำกับด้วยคีย์เวิร์ด final ในประโยคคำสั่งสร้างคลาส

public final MyClass {

}

     หรือในกรณีที่เราไม่ต้องการให้เมธอดของเราถูกโอเวอร์ไรด์ เราจะใช้การกำกับด้วยคีย์เวิร์ด final ในประโยคคำสั่งสร้างเมธอด

public final myMethod {

}

คุณสมบัติความหลากหลายรูปแบบ (Polymorphism) ของคลาส

     ในโลกจริงลองนึกถึงว่าบทบาทของคนแต่ละคนสามารถเป็นได้หลายอย่างขึ้นอยู่กับช่วงเวลา เช่น บทบาทของสมชายจะเป็นพ่อที่เตรียมอาหารให้ลูกตอนเช้าจากนั้นไปทำงานเป็นครูที่โรงเรียนและตอนเย็นเป็นพ่อค้าลูกชิ้นทอด สรุปว่าสมชายเป็น พ่อ ครู พ่อค้า และทั้งหมดนี้คือสมชายคนเดียวกันนี้เอง เราเรียกลักษณะนี้ว่าคุณสมบัติความหลากหลายรูปแบบ

     ในภาษาจาวาคุณสมบัติความหลากหลายรูปแบบหมายถึงการที่ออบเจกต์สามารถมีพฤติกรรมที่แตกต่างกันไปแม้ว่าจะถูกประกาศจากคลาสเดียวกันก็ตาม โดยอาศัยคุณสมบัติการสืบทอด การโอเวอร์ไรด์เมธอด และการโอเวอร์โหลดเมธอด 

     คุณสมบัติการสืบทอดช่วยให้เราสร้างคลาสลูกที่มีลักษณะเดียวกันกับคลาสแม่แต่สามารถเปลี่ยนแปลงพฤติกรรมบางอย่างได้ด้วยการโอเวอร์ไรด์เมธอด     

     การโอเวอร์ไรด์เมธอดทำให้เราสามารถเปลี่ยนแปลงพฤติกรรมและผลลัพธ์ให้กับออบเจกต์ชนิดเดียวกันได้ และการโอเวอร์โหลดเมธอดทำให้เราสามารถเพิ่มความหลากหลายของการเรียกใช้งานออบเจกต์ได้ 

     ตัวอย่างเช่น เราสร้างคลาส Car และสร้างคลาส SportCar และคลาส Ecocar ซึ่งเป็นคลาสลูกที่สืบทอดมาจากคลาส Car โดยในคลาสลูกได้โอเวอร์ไรด์เมธอด maxSpeed ของคลาส Car ดังตัวอย่างในบรรทัดที่ 10 ของคลาส SportCar และดังตัวอย่างในบรรทัดที่ 9  ของคลาส EcoCar

     จากนั้นเราสร้างออบเจกต์โดยประกาศตัวแปรด้วยคลาส Car และสร้างออบเจกต์ด้วยคลาสลูกที่ต้องการ ดังตัวอย่างในบรรทัดที่ 7 และ 8

     ให้สังเกตุว่าการใช้งานจะแตกต่างจากการสร้างออบเจกต์ทั่วๆไปซึ่งจะประกาศชนิดข้อมูลและสร้างออบเจกต์ด้วยคลาสเดียวกัน แต่ในการใช้งานคุณสมบัติความหลากหลาย (Polymorphism) เราจะประกาศชนิดข้อมูลด้วยคลาสแม่แต่สร้างออบเจกต์ด้วยคลาสลูก 

     หากเราดูในรายละเอียดของการสร้างออบเจกต์จะพบว่า ด้วยคุณสมบัติการสืบทอดจะทำให้คลาสลูกมีฟิลด์และเมธอดเหมือนกับคลาสแม่ แต่เราสามารถโอเวอร์ไรด์เมธอดให้มีพฤติกรรมที่แตกต่างกัน ดังนั้นเมื่อเราใช้ชนิดข้อมูลเป็นคลาสแม่ แต่สร้างออบเจกต์ด้วยคลาสลูกจึงทำให้เราได้ออบเจกต์ที่เป็นเรื่องเดียวกันกับคลาสแม่แต่มีพฤติกรรมบางอย่างแตกต่างกันออกไป

     ในการทำความเข้าใจให้แยกเรื่องคลาสและออบเจกต์ออกจากกัน คลาสเป็นแผนผังในการสร้างออบเจกต์ เราใช้งานออบเจกต์ที่สร้างขึ้นมา ดังนั้นด้วยคุณสมบัติการสืบทอด (ลดเวลาการเขียนแผนผังลงไป) การโอเวอร์ไรด์เมธอด (เปลี่ยนแปลงพฤติกรรม) การโอเวอร์โหลดเมธอด (เรียกใช้งานได้ด้วยค่าที่แตกต่างกัน) ทำให้เราได้แผนผังของวัตถุชนิดเดียวกันที่มีพฤติกรรมแตกต่างกันและยืดหยุ่นในการเรียกใช้งาน 

คุณสมบัติการประกาศรูปแบบ (Abstraction) ของคลาส

     คุณสมบัติการประกาศรูปแบบ (Abstraction) สามารถมองได้ 2 ความหมาย คือ การแสดงภาพย่อๆของสิ่งที่ต้องการ โดยซ่อนความซับซ้อนไว้และแสดงให้เห็นเฉพาะสิ่งที่ต้องใช้งาน เช่น การทำงานของตู้เอทีเอ็มซึ่งเราไม่ต้องรู้ว่าเมื่อเราถอนงินนั้นเกิดกิจกรรมต่างๆมากมายทั้งที่ตัวตู้เองไปจนถึงการลงบัญชีในระบบคอมพิวเตอร์ของของธนาคาร  Java API ก็เป็นแอบแสตรคเช่นเดียวกัน เช่น คลาสที่ช่วยเราจัดการเรื่อง I/O เป็นต้น ส่วนอีกความหมาย คือ เป็นการประกาศและสัญญาว่าคลาสจะมีชื่อเมธอดและพารามิเตอร์ตามที่ประกาศไว้เสมอ จึงเป็นเหมือนการกำหนดมาตรฐานในการเชื่อมต่อให้กับแอบแสตรคคลาส ดังนั้นคลาสลูกที่สืบทอดมาจากแอบแสตรคคลาส ก็จะถูกบังคับให้มีมาตรฐานการเชื่อมต่อในแบบเดียวกัน เราอาจจะมองว่าลักษณะการกำหนดแบบนี้เป็นเหมือนเฟรมเวิร์คแบบง่ายๆก็ได้

     ตัวอย่างประโยชน์ของการใช้คุณสมบัติการประกาศรูปแบบ เช่น หากเราสร้างคลาสขึ้นมาและมีผู้เรียกใช้งาน แต่ต่อมาเรามีการแก้ไขชนิดข้อมูลในพารามิเตอร์ของเมธอด นั่นจะทำให้โปรแกรมที่มาเรียกใช้งานคลาสของเราจะมีข้อผิดพลาดหรือปัญหาเกิดขึ้น ดังนั้นการใช้คุณสมบัติการประกาศรูปแบบจะเพิ่มความเชื่อมั่นให้แก่ผู้ที่จะมาใช้คลาสของเราว่าคลาสของเราจะไม่สร้างปัญหาให้กับโปรแกรมของเขาในอนาคตจากการปรับปรุงหรือเปลี่ยนแปลงและยังส่งเสริมการเป็น API ด้วย

     การเขียนโปรแกรมให้มีคุณสมบัติแบบนี้จะเป็นการใช้งานคลาสแบบ อินเตอร์เฟส (Interface) และคลาสแบบแอบแสตรค (Abstract Class) ซึ่งคลาสทั้ง 2 แบบจะไม่สามารถนำไปสร้างออบเจกต์ได้ แต่จะเป็นแม่แบบให้กับคลาสลูกที่สืบทอดมาจากคลาสทั้ง 2 แบบอีกทีหนึ่ง โดยภาษาจาวาจะบังคับว่าคลาสลูกที่สืบทอดมาจากคลาสแบบอินเตอร์เฟสและคลาสแบบแอบแสตรคจะต้องมีเมธอดตามที่คลาสแม่กำหนดไว้

คลาสแบบอินเตอร์เฟส (Interface class)

     คลาสแบบอินเตอร์เฟส (Interface) จะเป็นคลาสที่ไม่มีการประกาศฟิลด์ มีเฉพาะการประกาศเมธอดและพารามิเตอร์ และไม่มีรายละเอียดโปรแกรมในบล็อกเมธอด โดยเมธอดที่ประกาศในคลาสแบบอินเตอร์เฟสจะเป็นเมธอดที่คลาสลูกจะต้องมี ตัวอย่างเช่น

     การใช้งานคลาสแบบอินเตอร์เฟสทำได้โดยการสร้างคลาสลูกที่สืบทอด จากคลาสแบบอินเตอร์เฟสโดยเติมคีย์เวิร์ด implement และตามด้วยชื่อคลาสแบบอินเตอร์เฟส ตามรูปแบบดังนี้

class ชื่อคลาส implements ชื่อคลาสแบบอินเตอร์เฟส

     ตัวอย่างเช่น

         ตามหลักการเขียนโปรแกรมภาษาจาวา คลาสเป็นบล็อกที่ใหญ่ที่สุดและเราจะใช้คีย์เวิร์ดควบคุมการเข้าถึงแบบ public เสมอ ซึ่งหมายถึงคลาสจะสามารถถูกเรียกใช้ได้ทั้งจากภายในแพคเกจที่คลาสอยู่และจากภายนอกแพคเกจ หากเราต้องการให้คลาสถูกเรียกใช้ได้จากภายในแพคเกจที่คลาสอยู่เท่านั้นเราจะไม่กำหนดคีย์เวิร์ดควบคุมการเข้าถึงและเรียกคลาสแบบนี้ว่า package-private 

     นอกจากการระบุการสืบทอดแล้ว ยังต้องสร้างเมธอดตามที่ประกาศไว้ในคลาสแบบอินเตอร์เฟสโดยการโอเวอร์ไรด์เมธอด ตัวอย่างเช่น

     ในมุมมองของผู้ที่จะเรียกใช้งานโปรแกรม การใช้คลาสแบบอินเตอร์เฟสจะเป็นการยืนยันว่าชื่อเมธอดและพารามิเตอร์จะไม่มีการเปลี่ยนแปลง ส่วนในมุมมองของผู้พัฒนาโปรแกรม การใช้คลาสแบบอินเตอร์เฟสจะช่วยให้เราสามารถสร้างคลาสได้หลายหลายรูปแบบ (Polymorphism) ในขณะที่รูปแบบการเรียกใช้เมธอดของแต่ละคลาสลูกจะเหมือนๆกันทำให้ง่ายต่อผู้ที่จะมาใช้งาน รวมถึงมีความยืดหยุ่นในการแก้ไขหรือเปลี่ยนแปลงโปรแกรมภายในเมธอดในภายหลังโดยที่ไม่ส่งผลกระทบกับโปรแกรมอื่นที่มาเรียกใช้งานคลาสของเราเพราะชื่อเมธอดและพารามิเตอร์ยังเหมือนเดิม

     ตัวอย่างเช่น เราเขียนโปรแกรมเพื่อให้ตัวละครในเกมส์สามารถเปลี่ยนยานพาหนะได้ โดยเราจะสร้างคลาสแบบอินเตอร์เฟสของยานพาหนะชนิดต่างๆซึ่งยานพาหนะทุกชนิดจะมีเมธอดที่เหมือนๆกันคือ การเร่งความเร็ว การเลี้ยวซ้าย เป็นต้น ในขณะที่ลักษณะการใช้งานของยานพาหนะแต่ละชนิดจะแตกต่างกันไป เช่น รถยนต์ใช้พวงมาลัยบังคับเลี้ยวและใช้เท้าเหยียบคันเร่ง ส่วนรถเอทีวีใช้แฮนด์บังคับเลี้ยวและมีคันเร่งที่แฮนด์ เป็นต้น ดังนั้นเราจะสร้างคลาสแบบอินเตอร์เฟสชื่อ IVehicle โดยมีเมธอดในการเร่งความเร็วและการเลี้ยวซ้าย เพื่อประกาศเป็น API มาตรฐานสำหรับการใช้ยานพาหะทุกชนิดและสร้างคลาสลูกสำหรับยานพาหนะแต่ละแบบขึ้นมาซึ่งความแตกต่างของวิธีการเร่งความเร็วและการเลี้ยวซ้ายของรถยนต์และรถเอทีวีจะถูกเขียนไว้ในเมธอดที่ถูกโอเวอร์ไรด์ในแต่ละคลาสลูกนั่นเอง

          ในโปรแกรม IntelliJ IDEA การสร้างคลาสแบบอินเตอร์เฟสทำโดยไปที่พื้นที่แสดงโครงสร้างไฟล์ทางด้านซ้าย ไปที่ชื่อโครงงาน > src และคลิกขวาที่ชื่อแพคเกจซึ่งในที่นี้คือ com.company เลือก New และเลือก Interface การกำหนดชื่อคลาสแบบอินเตอร์เฟสใช้หลักการเดียวกันกับการตั้งชื่อคลาสและไม่ต้องกำกับด้วยคีย์เวิร์ดควบคุมการเข้าถึงสำหรับแต่ละเมธอด เพราะเมธอดในคลาสแบบอินเตอร์เฟสจะเป็น public เสมอ และหากมีการกำหนดฟิลด์ ฟิลด์จะเป็นแบบคอนแสตนท์เสมอ จึงควรตั้งชื่อฟิลด์ตามหลักการตั้งชื่อฟิลด์แบบคอนแสตนท์

     จากนั้นจึงสร้างคลาสลูกของยานพาหนะแต่ละชนิดและกำกับด้วยคีย์เวิร์ด implements ตามด้วยชื่อคลาสแบบอินเตอร์เฟส ซึ่งในเบื้องต้นโปรแกรม IntelliJ IDEA จะแสดงข้อผิดพลาดว่าคลาสลูกของเราต้องมีเมธอดตามที่กำหนดไว้ในคลาสแบบอินเตอร์เฟส

     ในการโอเวอร์ไรด์เมธอดตามที่กำหนดในคลาสแบบอินเตอร์เฟสทำโดยไปที่เมนู Code > Generate และเลือก ImplementMethods…  IntelliJIDEA จะแสดงเมธอดทั้งหมดในคลาสแบบอินเตอร์เฟสซึ่งเราต้องเลือกทั้งหมด แต่ถ้าเมธอดใดไม่ใช้ก็ไม่ต้องเขียนโปรแกรมในบล็อกเมธอดนั้นๆ ตัวอย่างเมธอดที่เกิดจากการโอเวอร์ไรด์ในบรรทัดที่ 19 และ 25 ของคลาส Car และในบรรทัดที่ 18 และ 24 ของคลาส Atv

     จากตัวอย่างด้านบนเราสร้างคลาสลูกของยานพาหนะขึ้นมา 2 คลาสคือคลาส Car และคลาส ATV โดยคลาสลูกทั้ง 2 คลาสจะมีเมธอดสำหรับเร่งความเร็วและเลี้ยวซ้ายเหมือนกันแต่วิธีการจะต่างกัน ซึ่งทำให้แต่ละคลาสลูกประกาศเมธอดในมาตรฐานเดียวกัน

     สำหรับการใช้งานเราสามารถสร้างออบเจกต์ด้วยประกาศชนิดข้อมูลเป็นคลาสลูกและสร้างออบเจกต์โดยการอ้างอิงคลาสลูก ดังตัวอย่างด้านล่าง

     หรือประกาศชนิดข้อมูลด้วยคลาสแบบอินเตอร์เฟสแต่สร้างออบเจกต์โดยการอ้างอิงคลาสลูก ดังตัวอย่างด้านล่าง 

     ซึ่งการประกาศชนิดข้อมูลด้วยคลาสแบบอินเตอร์เฟสแต่สร้างออบเจกต์โดยการอ้างอิงคลาสลูกจะมีความยืดหยุ่นมากกว่าในกรณีที่เราต้องการเปลี่ยนชนิดของออบเจกต์ที่สร้างมาจากคลาสลูกในภายหลังโดยไม่ต้องแก้ไขโปรแกรม เช่น หากเราต้องการให้ตัวละครในเกมส์เปลี่ยนยานพาหนะได้โดยที่เราไม่ต้องตามไปแก้ไขโปรแกรมในส่วนอื่น ตัวอย่างเช่น

     เนื่องจากการประกาศชนิดข้อมูลด้วยคลาสแบบอินเตอร์เฟสแต่สร้างออบเจกต์โดยการอ้างอิงคลาสลูกนั้นตัวแปรจะเป็นชนิดข้อมูลคลาสแบบอินเตอร์เฟส ดังนั้นถ้าเราต้องการเรียกเมธอดที่สร้างขึ้นมาเพิ่มเติมเฉพาะสำหรับแต่ละคลาสซึ่งไม่ได้ประกาศไว้ในคลาสแบบอินเตอร์เฟสจะไม่สามารถทำได้ นอกจากว่าเราต้อง cast ตัวแปรด้วยชื่อของคลาสลูกเสียก่อน คือเรามองว่าคลาสเป็นชนิดข้อมูลแบบนึง จึงนำมา cast ได้เหมือนกับที่เราเรียนรู้มาในหัวข้อ primitive data type และเมื่อเรา cast แล้วจึงจะสามารถเรียกใช้เมธอดเหล่านั้นได้ เช่น เราต้องการเรียกใช้เมธอด getspeed() ในคลาส Car เราต้อง cast ตัวแปร myVehicle ด้วยชนิดข้อมูล Car เสียก่อนดังตัวอย่างด้านล่าง

     เราสามารถสืบทอดคลาสแบบอินเตอร์เฟสได้มากกว่าหนึ่งคลาสโดยใช้

อักขระ ,  คั่นระหว่างชื่อคลาสแบบอินเตอร์เฟส เราจึงสามารถแยกแยะกลุ่มของเมธอดได้อย่างยืดหยุ่น เช่น เราเรียกใช้คลาสแบบอินเตอร์เฟส IVehicle สำหรับการสร้างยานพาหนะและเรียกใช้คลาสแบบอินเตอร์เฟส IWeapon เพื่อติดอาวุธให้กับยานพาหนะ 

คลาสแบบแอบแสตรค (Abstract class)

     คลาสแบบแอบแสตรคคือคลาสที่ใช้ในการกำหนดว่าคลาสลูกจะต้องมีเมธอดตามที่กำหนดในคลาสแม่ ส่วนประกอบต่างๆในคลาสแบบแอบ

แสตรคจะเหมือนกับคลาสทั่วๆไปเพียงแต่ระบุคีย์เวิร์ด abstract ทั้งในระดับคลาสและเมธอดที่ต้องการ และไม่มีรายละเอียดของโปรแกรมในบล็อกของเมธอดที่ระบุด้วยคีย์เวิร์ด abstract ตัวอย่างเช่น

      การใช้งานคลาสแบบแอบแสตรคทำโดยสร้างคลาสลูกที่สืบทอดมาจากคลาสแบบแอบแสตรคด้วยการระบุคีย์เวิร์ด extends เช่นเดียวกับการสืบทอดคลาสตามปรกติ และโอเวอร์ไรด์เมธอดตามที่กำหนดโดยไปที่เมนู Code > Generate และเลือก ImplementMethods…  โปรแกรม IntelliJIDEA จะแสดงเมธอดทั้งหมดในคลาสแบบแอบแสตรคซึ่งเราต้องเลือกทั้งหมด แต่ถ้าเมธอดใดไม่ใช้ก็ไม่ต้องเขียนโปรแกรมในบล็อกนั้นๆ 

     สำหรับการใช้งานเราสามารถสร้างออบเจกต์ด้วยประกาศชนิดข้อมูลได้ทั้งแบบ ประกาศเป็นคลาสลูกและสร้างออบเจกต์โดยการอ้างอิงคลาสลูก หรือประกาศชนิดข้อมูลด้วยคลาสแบบแอบแสตรคแต่สร้างออบเจกต์โดยการอ้างอิงคลาสลูก และถ้าเราต้องการเรียกเมธอดที่สร้างขึ้นมาเพิ่มเติมเฉพาะสำหรับแต่ละคลาสลูกโดยที่ไม่ได้ประกาศไว้ในคลาสแบบแอบแสตรคจะต้อง cast ตัวแปรด้วยชื่อของคลาสลูกเสียก่อน เช่นเดียวกับคลาสแบบอินเตอร์เฟส

     ข้อแตกต่างระหว่างคลาสแบบอินเตอร์เฟสและคลาสแบบแอบแสตรกคือเราสามารถกำหนดฟิลด์และเมธอดอื่นๆในคลาสแบบแอบแสตรคได้ซึ่งก็จะมีความยืดหยุ่นที่แตกต่างไปจากคลาสแบบอินเตอร์เฟส และเราสามารถสร้างคลาสแบบแอบแสตรคที่สืบทอดมาจากคลาสแบบแอบแสตรคได้ด้วย

     เราสามารถใช้งานคลาสแบบแอบแสตรคและคลาสแบบอินเตอร์เฟสด้วยกันได้ เช่น ในกรณีที่บางเมธอดอาจจะไม่ได้เหมาะที่จะกำหนดให้สืบทอดลงมาเนื่องด้วยเป็นคุณลักษณะเฉพาะสำหรับบางออบเจกต์ไม่ใช่สำหรับทุกออบเจกต์ เราสามารถแยกเอาเมธอดดังกล่าวมากำหนดเป็นคลาสแบบอินเตอร์เฟสแล้วนำไปใช้กับร่วมกับคลาสลูกที่สืบทอดมาจากคลาสแบบแอบแสตรคก็ได้ ตัวอย่างเช่น เฉพาะรถสปอร์ตเท่านั้นที่เราจะติดตั้งสปอยเล่อร์ เราจึงแยกเอาเมธอดการปรับสปอยเล่อร์ตามความเร็วออกมาต่างหาก และเอามาใช้กับคลาส  SportCar ที่สืบทอดมาจากคลาส AbstractVehicle ดังตัวอย่างด้านล่าง

การสร้างคลาสที่เปลี่ยนแปลงไม่ได้ (Immutable Class)

     เนื่องจากการสร้างคลาสส่วนใหญ่คือการสร้างคลาสที่จะเป็นส่วนหนึ่งของแอพพลิเคชั่นอีกทีหนึ่ง ดังนั้นคลาสที่ถูกสร้างขึ้นมาย่อมจะถูกเรียกใช้งานจากโปรแกรมอื่นๆหรือคลาสอื่นๆ ดังนั้นคลาสที่ดีจะต้องเชื่อถือได้ว่าออบเจกต์ที่สร้างขึ้นมาจากคลาสจะต้องไม่ก่อให้เกิดปัญหาในการใช้งาน (run time error) และการทำงานของออบเจกต์จะต้องเป็นไปตามที่เรากำหนดไว้เท่านั้น ดังนั้นเพียงใช้คุณสมบัติการห่อหุ้ม (encapsulation) อาจจะไม่เพียงพอ จึงมีการนำความสามารถอื่นๆมาประกอบเพิ่มเติมและกำหนดเป็นแนวทางเพื่อสร้างคลาสที่เปลี่ยนแปลงไม่ได้ (immutable class)  

     คลาสที่เปลี่ยนแปลงไม่ได้ หมายถึงคลาสที่ไม่ยอมให้มีการเปลี่ยนแปลงสถานะของออบเจกต์หลังจากที่ออบเจกต์ถูกสร้างขึ้นมาโดยมีแนวทางในการสร้างคลาสที่เปลี่ยนแปลงไม่ได้ดังนี้

1. ห้ามมีเมธอด setter ในคลาส เพื่อไม่ให้มีช่องทางในการเปลี่ยนสถานะ

2. กำหนดให้ทุกฟิลด์เป็น private และ final หมายถึงค่าของฟิลด์จะถูกสร้างจากเมธอดคอนสตรัคเคอร์เท่านั้น

3. กำหนดให้คลาสเป็น final เพื่อป้องกันการสืบทอดและโอเวอร์ไรด์เมธอดเพื่อให้ทำงานแตกต่างออกไปจากที่ออกแบบไว้

4. หากฟิลด์ในคลาสมีออบเจกต์เป็นส่วนประกอบ ต้องหาทางป้องกันไม่ให้มีการแก้ไขออบเจกต์นั้นได้ เช่น ต้องไม่มีเมธอดที่สามารถแก้ไขออบเจกต์ดังกล่าวได้ หากเมธอดต้องมีการส่งค่าออบเจกต์กลับไป ให้ส่งสำเนาของออบเจกต์แทนที่จะส่งออบเจกต์ออกไปตรงๆ

คลาสที่มีได้แค่ออบเจกต์เดียว (SIngleton Class)

     ในบางครั้งเราอาจจะต้องการสร้างคลาสที่สามารถสร้างออบเจกต์ขึ้นมาได้เพียงตัวเดียว (อินแสตนซ์เดียว) เพื่อใช้งานในระบบอันอาจจะเนื่องมาจากเพื่อป้องกันไม่ให้เกิดการทำงานซ้ำซ้อน เพื่อให้มีข้อมูลอ้างอิงเดียวกันจากทั้งระบบ หรือด้วยเหตุผลอื่นๆ การสร้างคลาสแบบซิงเกิ้ลตั้นทำได้โดย

1. สร้างฟิลด์ด้วยชนิดข้อมูลเดียวกันกับชื่อคลาสในแบบ private และ static

2. กำหนดให้เมธอดคอนสตรัคเตอร์เป็น private

3. การเข้าถึงออบเจกต์จะทำผ่าน getter และ setter เท่านั้นจึงต้องกำหนดให้เป็น public และ static โดย getter จะคืนค่าของออบเจกต์

     ตัวอย่างเช่น

public class SingletonClass {

     private static SingletonClass singletonInstance = new SingletonClass;

     // ฟิลด์อื่นๆในแบบ private ตามต้องการ

     private SingletonClass(){

     }

     public static SingletonClass getSingletonInstance(){

     return singletonInstance;    

     }

     // เมธอดเพื่อ get และ  set ฟิลด์อื่นๆ

}