Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 24 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
24
Dung lượng
366 KB
Nội dung
Bài 4: TÍNH KẾ THỪA & ĐA HÌNH GV Trần Trung Hiếu • Thiết kế lớp Nguoi trừu tượng, có chứa một vài phương thức trừu tượng phương thức cài đặt • Thiết kế lớp SinhVien, GiangVien, CBPB kế thừa từ lớp người với thuộc tính riêng, phương thức riêng cài đặt nội dung cho phương thức trừu tượng lớp người • Nhập từ bàn phím mảng Nguoi, thực hoạt động đóng thuế chung cho tất người thực hoạt động đóng học phí cho sinh viên Tính kế thừa (inheritance) • Tính kế thừa: Ta tạo lớp sở lớp cũ tạo trước Bắng cách thừa kế, ta sử dụng lại phương thức thuộc tính khai báo lớp cũ mà khai báo lại, bổ xung phương thức, thuộc tính cho lớp để giải toán với yêu cầu đặt • Subclass ~ lớp (lớp dẫn xuất) & Superclass – A: Subclass, B: Superclass lớp cha class A extends B { // … } Vd: Superclass Subclass public class Person{ private String name; public class Student extends Person { private int studentNumber; public Person ( ) { name = “no_name_yet”; } public Student ( ) { super( ); studentNumber = 0; } public Person ( String initialName ) { this.name = initialName; } public Student (String initialName, int initialStudentNumber) { super(initialName); studentNumber = initialStudentNumber; } public String getName ( ) { return name; } } public void setName ( String newName ) { name = newName; } public int getStudentNumber ( ) { return studentNumber; } public void setStudentNumber (int newStudentNumber ) { studentNumber = newStudentNumber; } Tính kế thừa • Nếu lớp tạo không khai báo thừa kế từ lớp khác mặc định thừa kế từ lớp Object • Vd: Object Person Student Thuộc tính cách thức lớp dẫn xuất • Một lớp dẫn xuất bao gồm phần: Các thuộc tính, cách thức riêng (locally) Các thuộc tính, cách thức kế thừa từ lớp cha Đâu thuộc tính, cách thức riêng lớp dẫn xuất Student ví dụ trước ? Constructors lớp dẫn xuất • Constructor lớp dẫn xuất triệu gọi constructor lớp cha cách sử dụng phương thức super • Nếu khơng có phương thức super sử dụng mặc định phương thức super() thêm vào dòng lệnh constructor lớp dẫn xuất gọi đến constructor không chứa tham số lớp cha • Constructor khơng thể thừa kế Hoạt động constructor class X { protected int x1 = 1; protected int x2; public X() { x2 = x1; } class Y extends X { protected int y1 = 2; public Y() { x2 = y1; } } } Y objectY = new Y(); Step what happens fields set to default values Y constructor invoked X constructor invoked Object constructor invoked X field initialization X constructor executed Y field initialization Y constructor executed x1 0 0 1 1 y1 x2 0 0 0 2 0 0 1 Overloading methods – Nạp chồng phương thức • Overloading: Cung cấp nhiều phương thức có tên khác danh sách tham số – Xuất class – Có tên phương thức – Khác danh sách tham số (kiểu, số lượng, thứ tự) – Có thể có kiểu trả khác Vd: phương thức print() lớp java.io.PrintStream public void print(boolean b) public void print(char c) public void print(String s) Overriding Methods – Ghi đè phương thức • Overriding: Thay nội dung thực phương thức lớp cha nội dung thực riêng lớp – – – – Xuất lớp dẫn xuất Có tên phương thức Có kiểu trả Chỉ định truy xuất phương thức ghi đè không thu hẹp so với phương thức lớp cha mà mở rộng • Nếu phương thức lớp cha public, phương thức lớp public • Nếu phương thức lớp cha protected, phương thức lớp public hay protected • Nếu phương thức lớp cha package, phương thức lớp package, protected, public • Nếu phương thức lớp cha private, khơng thừa kế nên ghi đè lớp – Phương thức ghi đè throws exception nằm danh sách lớp cha throws ra, lớp dẫn xuất exception Khi ghi đè phương thức ? • Một phương thức ghi đè truy cập trong lớp dẫn xuất hay nói cách khác thừa kế – Phương thức private lớp cha • Không thể ghi đè • Nếu lớp chứa đựng phương thức vậy, phương thức hồn tồn khơng liên quan tới phương thức lớp cha – Phương thức package lớp cha • Có thể ghi đè lớp dẫn xuất nằm gói với lớp cha – Phương thức protected, public • Ln ln ghi đè Một số ví dụ (1) package P1; public class Base { private void pri( ) { System.out.println(“Base.pri()”); } void pac( ) { System.out.println(“Base.pac()”); } protected void pro( ) { System.out.println(“Base.pro()”); } public void pub( ) { System.out.println(“Base.pub()”); } public final void show( ) { pri(); pac(); pro(); pub(); } } package P2; import P1.Base; public class Concrete1 extends Base { public void pri( ) { System.out.println(“Concrete1.pri()”); public void pac( ) { System.out.println(“Concrete1.pac()”); public void pro( ) { System.out.println(“Concrete1.pro()”); public void pub( ) { System.out.println(“Concrete1.pub()”); } Concrete1 c1 = new Concrete1(); c1.show( ); Output? Base.pri() Base.pac() Concrete1.pro() Concrete1.pub() } } } } Một số ví dụ (2) package P1; import P2.Concrete1; public class Concrete2 extends Concrete1 { public void pri( ) { System.out.println(“Concrete2.pri()”); public void pac( ) { System.out.println(“Concrete2.pac()”); public void pro( ) { System.out.println(“Concrete2.pro()”); public void pub( ) { System.out.println(“Concrete2.pub()”); } Concrete2 c2 = new Concrete2(); c2.show( ); Output? Base.pri() Concrete2.pac() Concrete2.pro() Concrete2.pub() } } } } Một số ví dụ (3) package P3; import P1.Concrete2; public class Concrete3 extends Concrete2 { public void pri( ) { System.out.println(“Concrete3.pri()”); public void pac( ) { System.out.println(“Concrete3.pac()”); public void pro( ) { System.out.println(“Concrete3.pro()”); public void pub( ) { System.out.println(“Concrete3.pub()”); } Concrete3 c3 = new Concrete3(); c3.show( ); Output? Base.pri() Concrete3.pac() Concrete3.pro() Concrete3.pub() } } } } Thuộc tính trùng tên lớp superclass subclass (hiding fields) • Nếu thuộc tính xuất lớp lớp cha (có thể khác kiểu) Khi muốn truy xuất tới thuộc tính lớp cha, phải dùng từ khóa super kèm • • Vd: // Hiding Fields Example class Book { String author, title, pu; // pu is publisher } //=============================================== class ShopBook extends Book { String pu; // pu is purchaser public ShopBook(String a, String t, String pub, String purch) { author=a; title=t; super.pu=pub; pu=purch; } public String toString() { return title + " by " + author + " (publisher: " + super.pu + ")" + "\npurchaser: " + pu; } public static void main(String[] args) { ShopBook b = new ShopBook("H Jones","Killjoy", "AB Pub Inc", "V Smith"); System.out.println(b); } } Tính đa hình - Polymorphism • Tính đa hình thể qua việc: phương thức có nội dung thực khác đối tượng khác • Phương thức gọi xác định thông qua đối tượng tham chiếu, không thông qua kiểu khai báo tham chiếu • Thuộc tính gọi xác định thông qua kiểu khai báo tham chiếu Example Classes class SuperShow { public String str = “SuperStr”; public void show( ) { System.out.println(“Super.show:” + str); } } class ExtendShow extends SuperShow { public String str = “ExtendedStr”; } public void show( ) { System.out.println(“Extend.show:” + str); } public static void main (String[] args) { ExtendShow ext = new ExtendShow( ); SuperShow sup = ext; sup.show( ); //1 ext.show( ); //2 methods invoked through object reference System.out.println(“sup.str = “ + sup.str); //3 System.out.println(“ext.str = “ + ext.str); //4 field access } Output? Extend.show: ExtendStr Extend.show: ExtendStr sup.str = SuperStr ext.str = ExtendStr Tương thích kiểu - Type compatibility E.g Student is subclass of Person %> javac typeTest.java public class TypeTest { static Person[] p = new Person[10]; TypeTest.java:17 incompatible types found : Person required : Student Student o3 = p[0]; ^ static { } for (int i = 0; i < 10; i++) { if(i java TypeTest Exception in thread “main” java.lang.ClassCastException: Person at typeTest.main(TypeTest.java:20) Test kiểu • Sử dụng tốn tử instanceof để test kiểu đối tượng e.g if ( obj instanceof String) { String str2 = (String)obj; } Lớp trừu tượng – abstract class • • Lớp thiết kế nhằm tạo lớp có đặc tính tổng qt, định nghĩa thuộc tính chung cho các lớp con Lớp trừu tượng: khai báo với từ khóa abstract, thường có phương thức trừu tượng, phương thức chưa cài đặt, việc cài đặt thực lớp thừa kế public abstract class Person { protected String name; public abstract String getDescription(); } Person Class Student extends Person { Employee private String code; pulic String getDescription() { return “student name: “ + name + “/n student code: ” + code; } } Class Employee extends Person { private float salary; pulic String getDescription() { return “an employee with a salary of $ “ + salary; } } Student Lớp trừu tượng – abstract class • Các phương thức chưa cài đặt lớp trừu tượng phải khai báo abstract • Nếu class có chứa phương thức abstract, class phải khai báo abstract • Khi thừa kế từ lớp trừu tượng có trường hợp xảy ra: Nếu lớp khai báo abstract (cũng lớp trừu tượng), cần cài đặt vài phương thức abstract lớp cha Nếu lớp khơng phải lớp trừu tượng, phải cài đặt tất phương thức abstract lớp cha • Khơng thể tạo các đối tượng của một lớp trừu tượng nhưng có thể khai báo biến thuộc kiểu lớp trừu tượng để tham chiếu đến đối tượng thuộc lớp con E.g Person p = new Student( ); Lớp vô sinh – final class • Lớp mà ta khơng thể có lớp dẫn xuất từ (khơng có lớp con) gọi lớp “vơ sinh”, hay nói cách khác khơng thể kế thừa từ lớp “vô sinh” Lớp “vô sinh” dùng để hạn chế, ngăn ngừa lớp khác dẫn xuất từ • Để khai báo lớp lớp “vơ sinh”, dùng từ khóa final class • Ví dụ: Lớp String Java final class, ta thừa kế viết phương thức length() riêng public final class String extends Object implements Serializable, Comparable, CharSequence Class Object in Java • Lớp Object lớp cha lớp Java, lớp Java thừa kế từ lớp mà không cần khai báo extends • Một số phương thức lớp Object – equals: cho biết hai tham chiếu đối tượng có giá trị hay không – toString: trả lại xâu đại diện cho đối tượng – > Khi cần sử dụng class cụ thể, thực overriden method phù hợp với yêu cầu đặt – > Tham khảo phương thức class String