Kế thừa inheritance Kế thừa là một trong các đặc điểm chính của Lập trình hướng đối tượng khi ta cần đặc biệt hoá đối tượng đã có: hãy sử dụng kế thừa bằng cách thêm một số thuộc tính
Trang 1LẬP TRÌNH
HƯỚNG ĐỐI TƯỢNG
Trang 2Chương 3
Kế thừa
inheritance
Trang 3Kế thừa (inheritance)
Kế thừa là một trong các đặc điểm
chính của Lập trình hướng đối tượng
khi ta cần đặc biệt hoá đối tượng đã có: hãy sử dụng kế thừa bằng cách thêm một số thuộc tính và phương
thức cần thiết
kế thừa giúp người lập trình tiết kiệm được thời gian và công sức vì không phải xây dựng lại từ đầu mọi thứ đã
có, sử dụng lại phần code đã viết
Trang 4ví dụ
ta đã xây dựng class Nguoi bao gồm các thuộc tính: họ tên, địa chỉ, , các phương thức nhập, xuất, hiệu chỉnh
ta có thể xây dựng lớp SinhViên thừa
kế từ lớp Người bằng cách thêm các
thuộc tính: MaSV, lớp và phương thức nhập (chỉ cần viết thêm phần nhập
MaSV, lớp), xuất (chỉ cần viết thêm
phần xuất MaSV, lớp,
Trang 5ví dụ
ta đã xây dựng lớp Điểm hai chiều bao gồm các thuộc tính x,y và phương
thức nhập, xuất, di chuyển,
ta có thể xây dựng lớp điểm có màu
kế thừa từ lớp điểm bằng cách bổ
sung thuộc tính màu,
ví dụ: Động vật chó
ví dụ: Nhân viên trưởng phòng
Trang 6 lớp cơ sở (base class): là lớp đã được xây dựng
lớp dẫn xuất(derived class): là lớp cần được xây dựng dựa trên lớp cơ sở
Lớp Cơ sở
Lớp dẫn xuất
Lớp Cơ sở
Lớp dẫn xuất
Lớp cha
Lớp con
Trang 7cách khai báo
[thuộc tính truy xuất] class <tên lớp dẫn xuất>:<tên lớp cơ sở>
//các thuộc tính bổ sung
// các phương thức thêm từ khoá new để định phương thức mới trùng tên với
phương thức cửa lớp cơ sở
Trang 8ví dụ
class Nguoi {
string ho;
string ten;
public Nguoi(){}
public Nguoi(string h,string t)
Public Nguoi(Nguoi ng1) {ho=ng1.ho;ten=ng1.ten;}
public void xuat() {
Console.Write(“Ho va ten:{0} {1}”,ho,ten);
} }
Trang 9class SinhVien:Nguoi
{
string masv;
public SinhVien (string h,string t,string m) : base(h,t)
{
masv=m;
}
public new void xuat()
{
base.xuat();
Console.Write(“ Ma SV:{0}”,masv);
}
}
gọi hàm xuat() của lớp
Nguoi
gọi hàm thiết lập 2 tham số của lớp
Nguoi gọi hàm xuat() của lớp
Nguoi
Trang 10kiểm thử
static void Main()
{
Nguoi ng1=new Nguoi(“Nguyen Van”, “Tèo”); ng1.xuat();
SinhVien sv1=new SinhVien(“Tran Van”, “Coi”,
“310712222”);
sv1.xuat();
}
chạy chương trình bằng F11 (debug)
Trang 11Ghi chú
thêm từ khoá new vào trước khai báo phương thức
để định nghĩa lại phương thức của lớp dẫn xuất có trùng tên với phương thức cửa lớp cơ sở
base([các tham số…]): gọi hàm thiết lập của lớp dẫn xuất
base.tên phương thức(…): gọi thực hiện phương thức của lớp cơ sở
Khai báo hàm thiết lập của lớp dẫn xuất
public tên hàm thiết lập(…): base(…) {…}
Khi tạo đối tượng của lớp dẫn xuất thì sẽ thực hiện hàm thiết lập của lớp cơ sở trước sau đó thực hiện phần thân của hàm thiết lập của lớp dẫn xuất
Trang 12Nhắc lại Access modifier
Private: lớp con không nhìn thấy thành phần
private của lớp cha
Protected:
– Phạm vi trong lớp con: nhìn thấy và có quyền truy xuất thành phần protected của lớp cha
– Phạm vi ngoài lớp con: không nhìn thấy tức là các
instance không nhìn thấy thành phần protected
Public: trong và ngoài lớp con đều nhìn thấy thành phần public của lớp cha
Internal: trong và ngoài lớp con đều nhìn thấy
thành phần internal của lớp cha (cùng assembly)
Protected internal: hoặc thoả protected hoặc thoả internal
Trang 13Tóm lại
Lớp con được phép truy xuất các thành phần protected, internal và public của lớp cha
Trang 14Sự chuyển kiểu (casting)
long val = 30000;
int i = (int)val; // A valid cast The maximum int is 2147483647
long val = 3000000000;
int i = (int)val; // An invalid cast The maximum int is 2147483647
float f1 = 40.0;
long l1 = f1; // implicit short
s1 = (short) l1; // explicit, old C style
short s2 = short (f1); // explicit, new C++ style
float f1 = 40.0f;
long l1 = (long)f1; // explicit due to possible rounding error
short s1 = (short) l1; // explicit due to possible overflow error
int i1 = s1; // implicit _ no problems
uint i2 = (uint)i1; // explicit due to possible sign error
Trang 15Sự chuyển kiểu
Boxing/unboxing
long a = 333333423;
object b = (object)a;
int c = (int)b;
int j = 10;
object boxedJ = j; // boxing
int k = (int) boxedJ; // unboxing
Trang 16public class DONGVAT
{
string ten;
float cannang;
public DONGVAT() {
ten="DV";
cannang=0;
} public DONGVAT( string t,float cn) {
this.ten=t;
this.cannang=cn;
} public void keu() {
Console.Write("\n AAA!!!");
} public void xuat() {
Console.Write("\nTen: "+ten+"\nCan nang: "+cannang+" Kg"); }
}
Lớp con mèo Lớp Động vật
Trang 17class MEO:DONGVAT
{
string maulong;
public MEO():base() {
maulong = "";
} public MEO (string ten, float cannang, string maulong): base(ten, cannang)
{
this.maulong = maulong;
} public new void keu() {
Console.Write("\n MEO MEO!!!");
} public new void xuat() {
base.xuat();
Console.Write("\n mau long:{0}", maulong);
}
Trang 18static void Main()
{
DONGVAT dv1 = new DONGVAT();
dv1.xuat();
dv1.keu();
MEO m1 = new MEO("mimi", 3, "muop"); m1.xuat();m1.keu();
MEO m2 = new MEO(“binbin", 2, “mun"); m2.xuat();m2.keu()
m1=(MEO)dv1;//error :lỗi
dv1=m1;//boxing
dv1.xuat();dv1.keu();
m2=(MEO)dv1; //unboxing
m2.xuat();m2.keu()
}