Mục lục chương I: ĐỐi tưỢng và LỚP


Mở rộng một giao diện và sự thực thi nhiều giao diện của một lớp



tải về 1.36 Mb.
trang28/28
Chuyển đổi dữ liệu21.12.2018
Kích1.36 Mb.
1   ...   20   21   22   23   24   25   26   27   28

Mở rộng một giao diện và sự thực thi nhiều giao diện của một lớp


Bài 1.

Xây dựng giao diện nhân viên bao gồm hai phương thức: Nhập và hiển thị thông tin của cán bộ. Ta có thể xây dựng thêm một giao diện nhân viên mới mở rộng từ giao diện nhân viên. Giao diện nhân viên mới này xây phương thức cách tính lương cho mỗi loại nhân viên.

Hãy xây dựng lớp nhân viên sản xuất thực thi hai giao diện trên. Biết cách tính lương nhân viên như sau:

Lương=Hsl*Lương cơ bản

a, Hướng dẫn:

Ở chương 3 chúng ta đã biết đến sự kế thừa của một lớp dẫn xuất, xong nó chỉ kế thừa được từ một lớp cơ sở. Như bài toán này chúng ta không thể xây dựng Class Nhanviensx kế thừa từ hai lớp là Nhanvien và Nhanvienmoi. Mục đích chúng ta muốn lớp Class Nhanviensx kế thừa và thực thi cả hai Nhanvien và Nhanvienmoi, do đó chúng ta phải xây chúng là hai giao diện.

Bài toán bao gồm có hai giao diện và một lớp thực thi giao diện: Interface Nhân viên, interface Nhân viên mới, Class Nhân viên sx

Các phương thức và thuộc tính

interface Nhanvien

{

void nhap();



void hien();

}

interface Nhanvienmoi:Nhanvien // Mở rộng giao diện Nhân viên



{

double luong();

}

class Nhanviensx:Nhanvien,Nhanvienmoi // Thực thi hai giao diện



{

private string ten;

private static int lcb;

private double hsl;

public Nhanviensx()

public virtual void nhap()

public virtual void hien()

public virtual double luong()

}

b, Bài giải mẫu:



using System;

interface Nhanvien

{

void nhap();



void hien();

}

interface Nhanvienmoi:Nhanvien

{

double luong();

}

class Nhanviensx:Nhanvien,Nhanvienmoi

{

private string ten;

private static int lcb;

private double hsl;

public Nhanviensx()

{

hsl = 2.5;



lcb=450;

}

public Nhanviensx(int hsl)

{

this.hsl=hsl ;

}

public virtual void nhap()

{

Console.Write("Nhap vao ho ten:"); ten=Console.ReadLine();



Console.Write("Nhap vao he so luong:");

hsl=float.Parse(Console.ReadLine());

}

public virtual void hien()

{

Console.WriteLine("Thong tin can hien thi");



Console.WriteLine("Ho ten nhan vien:{0}",ten );

Console.WriteLine("He so luong:{0}",hsl );

}

public virtual double luong()

{

return hsl*lcb ;

}

}

class tester



{

static void Main(string[] args)

{

Nhanviensx A = new Nhanviensx();



A.nhap();

A.hien();

Console.WriteLine("Luong cua nhan vien nay la:{0}", A.luong());

Console.ReadLine();

}

}



Kết quả sau khi chạy chương trình:


Nhập vào họ tên: Nguyễn Văn A

Nhập vào hệ số lương: 5

Thông tin cần hiển thị

Họ tên nhân viên: Nguyễn Văn A

Hệ số lương: 5

Lương của nhân viên này là: 2250




    1. Xây dựng lớp thực thi phủ quyết một giao diện


Bài 1

a) Xây dựng lớp “DaySo” để mô tả một dãy số, gồm các phương thức sau:

- Phương thức “nhap” dùng để nhập dãy số từ bàn phím

- Phương thức “print” dùng để in dãy số ra màn hình

- Hàm tạo DaySo(int n) dùng để khởi tạo một mảng gồm n phần tử

b) Xây dựng giao diện Sort như sau:

interface Sort

{

public void Sort();



}

c) Xây dựng các lớp “QuickSort”, “SelectionSort”, “InsertSort” bằng cách kế thừa từ lớp DaySo và triển khai giao diện Sort để thực hiệp việc sắp xếp: nổi bọt, chọn trực tiếp, chèn trực tiếp

a, Hướng dẫn:

Giả sử bạn muốn thiết kế phương thức sắp xếp chung để sắp xếp các phần tử. Phần tử ở đây có thể là mảng các đối tượng như dãy số, ma trận, lớp hoc viên. Các đối tượng này có thể được sắp xếp bằng các thuật toán khác nhau. Vậy bạn cần xác định một phương thức sắp xếp chung nhằm thực hiện sắp xếp các đối tượng. Cách thức sắp xếp các đối tượng như thế nào do từng thuật toán tự quyết định.Ta thấy bài toán vừa yêu cầu kế thừa vừa thực thi giao diện. Đây chính là tiến bộ của sử dụng giao diện so với lớp trừu tượng.

Các đối tượng của bài toán bạn đọc có thể xác định thấy rõ ngay ở phần đề bài.

Các thuộc tính và các phương thức

class dayso

{

public int[] a;



protected int n;

public dayso()

public dayso(int n)

public void nhap()

public void print()

}

interface sort



{

void sapxep();

}

class quicksort:dayso, sort



{

public void sapxep()

}

class selectsort:dayso,sort



{

public void sapxep()

}

class inserttionsort:dayso,sort



{

public void sapxep()

}

Lưu ý: Lớp dayso có 2 thuộc tính là n và mảng a hai thuộc tính này nó được các lớp dẫn xuất kế thừa và gọi ra để thực thi. Do vậy hai thuộc tính này phải được khai báo là Public.

b, Bài giải mẫu:



using System;

class dayso

{

public int[] a;



protected int n;

public dayso()

{

a = new int[5];



}

public dayso(int n)

{

a = new int[n];



}

public void nhap()

{

Console.Write("Nhap vao so phan tu cua day so:");



n = int.Parse(Console.ReadLine());

Console.WriteLine("Nhap vao thong tin cua day so:");



for (int i = 0; i < n; i++)

{

Console.Write("a[{0}]=", i);



a[i] = int.Parse(Console.ReadLine());

}

}



public void print()

{

for (int i = 0; i < n; i++)

Console.Write("{0}\t",a[i]);

Console.WriteLine();

}

}

interface sort



{

void sapxep();

}

class quicksort:dayso,sort

{

public void sapxep()

{

int i, j,x,tmp;



x=a[(n)/2];

i = n-1; j = n;



do

{

while (a[i] < x) i++;



while (a[j] > x) j--;

if (i <= j)

{

tmp = a[i];



a[i] = a[j];

a[j] = tmp;

i++; j--;

}

} while (i < j);



}

}

class selectsort:dayso,sort

{

public void sapxep()

{

int min,tmp,j;



for (int i = 0; i < n - 1; i++)

{

min=i;



for (j = i + 1; j < n; j++)

if (a[j] < a[min])

min = j;

tmp = a[min];

a[min] = a[i];

a[i] = tmp;

}

}



}

class inserttionsort:dayso,sort

{

public void sapxep()

{

int i,pos,k;

for (i = 0; i < n; i++)

{

k = a[i]; pos = i-1;



while ( pos >=0 && a[pos] > k)

{

a[pos + 1] = a[pos];



pos--;

}

a[pos + 1] = k;



}

}

}



class Tester

{

static void Main()

{

//sort a = new quicksort();



//selectsort a = new selectsort();

inserttionsort a = new inserttionsort();

a.nhap(); Console.Clear();

Console.WriteLine("Day truoc khi sap xep :");

a.print();

Console.WriteLine("Day sau khi sap xep :");

a.sapxep();

a.print();

Console.ReadKey();

}

}



Kết quả sau khi chạy chương trình:


Dãy trước khi sắp xếp:

2 5 3 2


Dãy sau khi sắp xếp:

2 2 3 5

Lưu ý: Ta có thể phủ quyết tất cả các phương thức của giao diện trong lớp thực thi cũng có thể chỉ phủ quyết một vài hoặc không phủ quyết một phương thức nào.

    1. Xây dựng lớp thực thi giao diện một cách tường minh


Ví dụ: Xây dựng lớp Document, thực thi hai giao diện Italk, Istorable . Giao diện Italk có phương thức Read() và Italk. Giao diện Istorable có phương thức Read() và Write().

a, Hướng dẫn:

Bài toán gồm có :1 lớp Class Document, và 2 giao diện Italk, Istorable.

Ta thấy lớp Document thực thi hai giao diện, và cả hai giao diện trên đều có phương thức Read (). Vậy làm thế nào để máy tính cũng như bạn đọc có thể biết rằng lớp Document thi hành phương thức Read() là của giao diện nào. Để giải quyết vấn đề này bằng cách thực hiện giao diện một cách tường minh.

Xây dựng các giao diện và lớp

interface Istorable

{

void Read();



void Write();

}

interface Italk



{

void Read();

void Italk();

}

class Document:Italk, Istorable



{

public Document(string s)

void Istorable.Read() // Cài đặt phương thức Read() của Istorable

public void Write()

puclic void Italk()

void Italk.Read() // Cài đặt phương thức Read() của ITalk

}

Lưu ý: Chúng ta phải ép kiểu thành giao diện để gọi Phương thức Read() của Istorable và Italk. Thực thi giao diện một cách tường minh cho phương thức Read() bằng cách gọi cả tên của giao diện.



b, Bài giải mẫu:

using System;

namespace bt

{

interface Istorable

{

void Read();

void Write();

}

interface ITalk

{

void ITalk();

void Read();

}

class Document:Istorable,ITalk

{

public Document(string s)

{

Console.WriteLine("Tao van ban {0}",s);



}

void Istorable.Read()

{

Console.WriteLine("Thuc thi Istorable.Read()");



}

public void Write()

{

Console.WriteLine("Thuc thi Istorable.Write()");



}

void ITalk.Read()

{

Console.WriteLine("Thuc thi ITalk.Read()");



}

public void ITalk()

{

Console.WriteLine("Thuc thi ITalk.ITalk");



}

}

class tester

{

static void Main(string[] args)

{

Document thedoc = new Document("Bai tap C#");



Istorable isdoc = thedoc as Istorable;

if (isdoc != null)

{

isdoc.Read();



}

ITalk itdoc = thedoc as ITalk;



if (itdoc != null)

{

itdoc.Read();



}

thedoc.Write();

thedoc.ITalk();

Console.ReadLine();

}

}

}



Kết quả sau khi chạy chương trình:




Tạo văn bản Bài tập C#

Thực thi Istorable.Read()

Thực thi Italk.Read()

Thực thi Istorable.Write()

Thực thi Italk.ITalk


  1. CÂU HỎI VÀ TRẢ LỜI


Câu 1: So sánh giữa lớp và giao diện?

Trả lời: Giao diện khác với lớp ở một số điểm sau: giao diện không cung cấp bất cứ sự thực thi mã nguồn nào cả. Điều này sẽ được thực hiện tại các lớp thực thi giao diện. Một giao diện đưa ra chỉ để nói rằng có cung cấp một số sự xác nhận hướng dẫn cho những điều gì đó xảy ra và không đi vào chi tiết. Một điều khác nữa là tất cả các thành viên của giao diện được giả sử là public ngầm định. Nếu chúng ta cố thay đổi thuộc tính truy cập của thành viên trong giao diện thì sẽ nhận được lỗi.

Giao diện chỉ chứa những phương thức, thuộc tính, sự kiện, chỉ mục. Và không chứa dữ liệu thành viên, bộ khởi dựng, và bộ hủy. Chúng cũng không chứa bất cứ thành viên static nào cả.



Câu 2: Sự khác nhau giữa giao diện và lớp trừu tượng?

Trả lời: Sự khác nhau cơ bản là sự kế thừa. Một lớp có thể kế thừa nhiều giao diện cùng một lúc, nhưng không thể kế thừa nhiều hơn một lớp trừu tượng.

Câu 3: Các lớp thực thi giao diện sẽ phải làm gì?

Trả lời: Các lớp thực thi giao diện phải cung cấp các phần thực thi chi tiết cho các phương thức, thuộc tính, chỉ mục, sự kiện được khai báo trong giao diện.

Câu 4: Có bao nhiêu cách gọi một phương thức được khai báo trong giao diện?

Trả lời: Có 4 cách gọi phương thức được khai báo trong giao diện:

- Thông qua lớp cơ sở tham chiếu đến đối tượng của lớp dẫn xuất

- Thông qua một giao diện tạo từ lớp cơ sở tham chiếu đến đối tượng dẫn xuất

- Thông qua một đối tượng dẫn xuất

- Thông qua giao diện tạo từ đối tượng dẫn xuất

Câu 5: Các thành viên của giao diện có thể có những thuộc tính truy cập nào?

Trả lời: Mặc định các thành viên của giao diện là public. Vì mục tiêu của giao diện là xây dựng cho các lớp khác sử dụng. Nếu chúng ta thay đổi thuộc tính này như là internal, protected hay private thì sẽ gây ra lỗi.

Câu 6: Chúng ta có thể tạo thể hiện của giao diện một cách trực tiếp được không?

Trả lời: Không thể tạo thể hiện của giao diện trực tiếp bằng khai báo new được. Chúng ta chỉ có thể tạo thể hiện giao diện thông qua một phép gán với đối tượng thực thi giao diện.

  1. CÂU HỎI VÀ BÀI TẬP TỰ LÀM


Câu hỏi:

Câu 1: Toán tử is được dùng làm gì trong giao diện?

Câu 2: Toán tử as có lợi hơn toán tử is về mặt nào khi được sử dụng liện quan đến giao diện ?

Câu 3: Giao diện là kiểu dữ liệu tham chiếu hay kiểu giá trị?

Câu 4: Khi thực thi giao diện với cấu trúc. Thì truy cập các thành viên của giao diện thông qua đối tượng hay thông qua tham chiếu giao diện là tốt nhất?

Câu 5: Số giao diện có thể được kế thừa cho một lớp?

Câu 6: Việc thực thi giao diện tường minh là thực thi như thế nào? Trong trường hợp nào thì cần thực hiện tường minh?

Bài tập:

Bài 1. Trong giao diện sau sai ở đâu?

public interface House

{

@Deprecated



void open();

void openFrontDoor();

void openBackDoor();

}

Bài 2. Hoàn thành chương trình sau:

interface Closable

{

void close();



}

class File implements Closable

{

@Override



public void close()

{

//... close this file...



}

}

Điều gì sẽ xảy ra? Bạn có thể giải thích tại sao?



Bài 3: Hãy viết một giao diện khai báo một thuộc tính ID chứa chuỗi giá trị. Viết một lớpEmployee thực thi giao diện đó.

Bài 4: Đoạn mã nguồn sau đây có lỗi hãy sử lỗi và hãy cho biết tại sao có lỗi này. Sau khi sửa lỗi hãy viết một lớp Circle thực thi giao diện này?

public interface osi

{

long with;



long height;

double area();

int side();

}

Bài 5: Chương trình sau đây có lỗi hãy sửa lỗi, biên dịch và chạy lại chương trình. Hãy giải thích tại sao chương trình lại lỗi.



using system;

interface Ipoint

{

int x

{

get;

set;

}

int y

{

get;

set;

}

}



class MyPoint

{

private int myX;



private int myY;

public MyPoint(int x,int y)

{

myX=x;



myY=y;

}

public int x

{

get { return myX ;}

set { myX=value ;}

}

public int y

{

get

{return myY;}



set

{myY=value ;}

}

}

class tester



{

private static void printpoint(Ipoint p)

{

Console.WriteLine("x={0},y={1}", p.x, p.y);



}

static void Main()

{

MyPoint p = new MyPoint(2, 3);



Console.Write("My point ");

printpoint(p);

Ipoint p2 = new Ipoint();

printpoint(p2);

Console.ReadLine();

}

}




Bài 6: Trong các cách khai báo sau cách khai báo giao diện nào là đúng. Cách khai báo nào sai thì hãy sửa lại cho đúng.

interface A

{

void print () {};

}

interface B

{

void print();

}

abstract interface C

{

print();



}

abstract interface D

{

abstract void print() {}

}


Bài 7: Xây dựng một giao diện IDisplay có khai báo thuộc tính Name kiểu chuỗi. Hãy viết hai lớp Dog và Cat thực thi giao diện IDisplay, cho biết thuộc tính Name là tên của đối tượng.


Tài liệu hướng dẫn thực hành Môn LTHDT với C#





Поделитесь с Вашими друзьями:
1   ...   20   21   22   23   24   25   26   27   28


Cơ sở dữ liệu được bảo vệ bởi bản quyền ©tieuluan.info 2019
được sử dụng cho việc quản lý

    Quê hương