Giáo án - Bài giảng: LẬP TRÌNH HƯỚNG đối TƯỢNG TRONG CSHARP - Pdf 13

Lời mở đầu
Trong chương trình đã học trước đây chúng ta đã được làm quen với
một phương pháp lập trình đã có từ rất lâu và đơn giản đó là lập trình hướng
cấu trúc. Đối với các chương trình nhỏ thì phương pháp này tương đối hiệu
quả. Tuy nhiên, ngày nay khi quy mô các chương trình máy tính càng lớn và
có độ phức tạp cao thì phương pháp lập trình truyền thống này trở nên rất kém
hiệu quả. Và phương pháp lập trình hướng đối tượng ra đời nhằm khắc phục
những nhược điểm của phương pháp lập trình cũ này.
Lập trình hướng đối tượng cung cấp 4 tính năng tạo nên sự khác biệt và
sức mạnh của nó khi so sánh với lập trình hướng cấu trúc là tính trừu tượng,
tính đóng gói, tính đa hình và tính kế thừa. Đặc biệt, khi kết hợp với một ngôn
ngữ lập trình mạnh hiện nay là C#, bộ đôi có khả năng giả
i quyết những bài
toán từ đơn giản đến phức tạp nhất.
Trong chương này, bạn sẽ được giới thiệu về nội dung quan trọng với
tiêu đề là “Lập trình hướng đối tượng trong C#”. Chương gồm 2 phần sau:
- Phần I: Lập trình hướng đối tượng.
Phần này giới thiệu về phương pháp tiếp cận hướng đối tượng trong lập
trình với các tính chất, khái niệm c
ủa nó.
- Phần II: Lập trình hướng đối tượng trong C#. Phần này đề cập
đến việc lập trình hướng đối tượng trong ngôn ngữ lập trình mạnh hiện nay là
C#, bao gồm việc khai báo lớp, thuộc tính, cách thực hiện các phương thức, kế
thừa và nạp chồng.


con). Cách thức phân tích và thiết kế như vậy chúng ta gọi là nguyên lý lập
trình từ trên xuống (top-down), để thể hiện quá trình suy diễn từ cái chung cho
đến cái cụ thể.
Các chương trình con là những chức năng độc lập, sự ghép nối chúng
lại với nhau cho chúng ta một hệ thống chương trình để giải quyết vấn đề đặt
ra. Chính vì vậy, cách thức phân tích một hệ thống lấy chương trình con làm
nền tảng, chương trình con
đóng vai trò trung tâm của việc lập trình, được
hiểu như phương pháp lập trình hướg về thủ tục. Tuy nhiên, khi phân tích để
thiết kế một hệ thống không nhất thiết phải luôn luôn suy nghĩ theo hướng
“làm thế nào để giải quyết công việc”, chúng ta có thể định hướng tư duy theo
phong cách “với một số đối tượng đã có, phải làm gì để giải quyết được công
việc đặt ra” hoặc phong phú hơn, “làm cái gì với một số đối tượng đã có đó”,
từ đó cũng có thể giải quyết được những công việc cụ thể. Với phương pháp
phân tích trong đó đối tượng đóng vai trò trùng tâm của việc lập trình như vậy,
người ta gọi là nguyên lý lập trình từ dưới lên (Bottom-up).

3
Lập trình hướng đối tượng liên kết cấu trúc dữ liệu với các thao tác,
theo cách mà tất cả thường nghĩ về thế giới quanh mình. Chúng ta thường gắn
một số các hoạt động cụ thể với một loại hoạt động nào đó và đặt các giả thiết
của mình trên các quan hệ đó.
Ví dụ1.1: Để dễ hình dùng hơn, chúng ta thủ nhìn qua các công trình
xây dựng hiện đại, như sân vận động có mái che hình vòng cung, nhữ
ng kiến
trúc thẩm mĩ với đường nét hình cong. Tất cả những sản phẩm đó xuất hiện
cùng với những vật liệu xây dựng. Ngày nay, không chỉ chồng lên nhau những
viên gạch, những tảng đá để tạo nên những quần thể kiến trúc (như Tháp
Chàm Nha Trang, Kim Tự Tháp, ), mà có thể với bêtông, sắt thép và không
nhiều lắm những viên gạch, người xây dựng cũng có thể thiết kế những công

các quan hệ đó. Hãy quan niệm thế giới theo kiểu cấu trúc cây, với các mức
xây dựng chi tiết hơn kế tiếp nhau cho các thế hệ sau so với các thế hệ trước.

4
Đây là phương pháp hiệu quả để tổ chức thế giới quanh chúng ta. Các chương
trình hướng đối tượng cũng làm việc theo một phương thức tương tự, trong đó
chúng cho phép xây dựng các các cơ cấu dữ liệu và thao tác mới dựa trên các
cơ cấu có sẵn, mang theo các tính năng của các cơ cấu nền mà chúng dựa trên
đó, trong khi vẫn thêm vào các tính năng mới.
Lập trình hướng đối tượng cho phép chúng ta tổ chức dữ liệ
u trong
chương trình theo một cách tương tự như các nhà sinh học tổ chức các loại
thực vật khác nhau. Theo cách nói lập trình đối tượng, xe hơi, cây cối, các số
phức, các quyển sách đều được gọi là các lớp (Class).
Một lớp là một bản mẫu mô tả các thông tin cấu trúc dữ liệu, lẫn các
thao tác hợp lệ của các phần tử dữ liệu. Khi một phần tử dữ liệu được khai báo
là phần t
ử của một lớp thì nó được gọi là một đối tượng (Object). Các hàm
được định nghĩa hợp lệ trong một lớp được gọi là các phương thức (Method)
và chúng là các hàm duy nhất có thể xử lý dữ liệu của các đối tượng của lớp
đó. Một thực thể (Instance) là một vật thể có thực bên trong bộ nhớ, thực chất
đó là một đối tượng (nghĩa là một đối tượng
được cấp phát vùng nhớ).
Mỗi một đối tượng có riêng cho mình một bản sao các phần tử dữ liệu
của lớp còn gọi là các biến thực thể (Instance variable). Các phương thức định
nghĩa trong một lớp có thể được gọi bởi các đối tượng của lớp đó. Điều này
được gọi là gửi một thông điệp (Message) cho đối tượng. Các thông điệp này
phụ thuộc vào đố
i tượng, chỉ đối tượng nào nhận thông điệp mới phải làm việc
theo thông điệp đó. Các đối tượng đều độc lập với nhau vì vậy các thay đổi

gần đây, thay thế cho "structured", công nghệ lập trình hướng thủ tục là công
nghệ mà đã được phát triển từ những năm 1970. Java là tổng hoà của hướng
đối tượng và nó không thể lập trình theo kiể
u hướng thủ tục mà bạn đã thoải
mái và quen thuộc với nó. Chúng tôi hi vọng với phần này - đặc biệt khi tổng
hợp cùng với các ví dụ được hỗ trợ trong text và các website quen thuộc - sẽ
giúp bạn đủ thông tin về OOP để trở thành đồng môn với Java.
Chúng ta sẽ bắt đầu với câu hỏi đó, trên bề mặt, dường như không có thứ
j làm với lập trình: Làm thế nào mà các công ty như Compad, Dell, Gateway
và các nhà sản xuất máy tính cá nhân khác lại tr
ở nên lớn và nhanh đến vậy?
Hầu hết mọi người đều cho rằng họ làm ra những máy tính tốt và bán chúng
với giá rẻ ở kỉ nguyên mà máy tính trở nên phát triển nhanh và gấp gáp.
Nhưng trong tương lai - họ đã sản xuất rất nhiều mô hình nhanh và đáp ứng lại
sự thay đổi nhanh chóng?
Một phần lớn của câu trả lời là những công ty này đã làm rất nhiều việc.
Họ đã mua các thiết bị
từ sự tin cậy của các đại lý và sau đó tập trung họ. Họ
thường không đầu tư thời gian và tiền bạc cho việc thiết kế và xây dựng sức
mạnh của hàng cung cấp, ổ đĩa, motherboard và các thiết bị khác. Điều này tạo
cho các công ty sản xuất ra một sản phẩm và tạo sự thay đổi một cách nhanh
chóng mà ít tốn kém tiền bạc nhất hơn là họ làm kĩ sư cho chính họ.
Các nhà sản xuất máy tính cá nhân đã mua "các chức năng đã được đóng
gói". Ví dụ, khi họ mua một bộ nguồn, họ đang mua một cái j đấy với các
thuộc tính (kích cỡ, hình dạng và ) và tất nhiên chức năng (bộ nguồn tốt, số
power hiển thị và những điều khác). Compad cung cấp một ví dụ cụ thể về
cách nó hoạt động hiệu quả. Khi Compad chuyển từ kĩ nghệ hầu h
ết các phần
trong máy để mua các phần khác, nó cải thiện từ dưới.
OOP Springs từ cùng một ý tướng. Chương trình của bạn được làm từ

bạn thường quen thuộc với lập trình hướng thủ tục( Gọi lại trong ngôn ngữ lập
trình Java, các thủ tục này thường được gọi là method calls).
Về cá nhân, một object tốt nhất không bao giờ thao tác trực ti
ếp với dữ
liệu bên trong của object khác, cũng không nên lộ dữ liệu cho object khác xử
lý trực tiếp. Tất cả mọi việc giao tiếp nên thông qua method. Bằng cách đóng
gói dữ liệu object, bạn giảm được tối đa, giảm sự phụ thuộc dữ liệu, thời gian
debug rút ngắn lại.
Tất nhiên, giống như module trong ngôn ngữ hướng thủ tục, bạn sẽ
không muốn một object cá nhân làm quá nhiều. Cả
việc thiết kế và debug đều
trở nên đơn giản khi bản xây dựng các object nhỏ để thực hiện vài nhiệm vụ,
hơn là xây dựng các object với các dữ liệu bên trong cực kì phức tạp với hàng
trăm các thủ tục thao tác dữ liệu.
Tóm lại, so sánh lập trình cấu trúc với chương trình con làm nền tảng:
Chương trình = Cấu trúc dữ liệu + Thuật giải
Trong lập trình hướng đối tượng chúng ta có:
Đối t
ượng = Phương thức + Dữ liệu

7
3.1.2 Các tính chất của lập trình hướng đối tượng:
Đối tượng (object): Các dữ liệu và chỉ thị được kết hợp vào một đơn vị
đầy đủ tạo nên một đối tượng. Đơn vị này tương đương với một chương trình
con và vì thế các đối tượng sẽ được chia thành hai bộ phận chính: phần các
phương thức (method) và phần các thuộc tính (property). Trong thực tế, các
phương thức của đối tượng là các hàm và các thuộc tính của nó là các biến,
các tham số hay h
ằng nội tại của một đối tượng (hay nói cách khác tập hợp
các dữ liệu nội tại tạo thành thuộc tính của đối tượng). Các phương thức là

t đối tượng. Chỉ có các phương thức nội tại của đối
tượng cho phép thay đổi trạng thái của nó. Việc cho phép môi trường bên
ngoài tác động lên các dữ liệu nội tại của một đối tượng theo cách nào là hoàn
toàn tùy thuộc vào người viết mã. Đây là tính chất đảm bảo sự toàn vẹn của
đối tượng.

8
c) Tính đa hình (polymorphism): Thể hiện thông qua việc gửi các
thông điệp (message). Việc gửi các thông điệp này có thể so sánh như việc gọi
các hàm bên trong của một đối tượng. Các phương thức dùng trả lời cho một
thông điệp sẽ tùy theo đối tượng mà thông điệp đó được gửi tới sẽ có phản
ứng khác nhau. Người lập trình có thể định nghĩa một đặc tính (chẳng hạn
thông qua tên củ
a các phương thức) cho một loạt các đối tượng gần nhau
nhưng khi thi hành thì dùng cùng một tên gọi mà sự thi hành của mỗi đối
tượng sẽ tự động xảy ra tương ứng theo đặc tính của từng đối tượng mà không
bị nhầm lẫn.
Thí dụ khi định nghĩa hai đối tượng "hinh_vuong" và "hinh_tron" thì có
một phương thức chung là "chu_vi". Khi gọi phương thức này thì nếu đối
tượng là "hinh_vuong" nó sẽ tính theo công thức khác với khi đố
i tượng là
"hinh_tron".
d) Tính kế thừa (inheritance): Đặc tính này cho phép một đối tượng có
thể có sẵn các đặc tính mà đối tượng khác đã có thông qua kế thừa. Điều này
cho phép các đối tượng chia sẻ hay mở rộng các đặc tính sẵn có mà không
phải tiến hành định nghĩa lại. Tuy nhiên, không phải ngôn ngữ định hướng đối
tượng nào cũng có tính chất này.
3.1.3 Các khái niệm trong lập trình hướng đối tượng

3.1.3.1 Đối tượng

Lớp chính là tập các đối tượng có cùng các thuộc tính và hành vi giống
nhau. Các thành phần của lớp có thể chia thành ba vùng quản lý chính:
+ Công khai (public),
+ Được bảo vệ (protected),
+ Riêng (private).

Con người
Tên: Nam
Tuổi: 28
Trọng lượng: 65 kgs

Hành động:
Đi
Nói
Suy nghĩ

Xe máy
Loại: Future
Màu: Đỏ
Năm: 1995

Hành động:
Khởi động
Ngừng
Chuyển động

Hình: Một đối tượng Con người và một đối tượng Xe máy

10



. Đi
. Nói
. Suy nghĩ

Lớp Xe máy
- Loại: Kiểu chuỗi
- Màu: Kiểu chuỗi
- Năm: Kiểu sốố

. Khởi động
. Ngừng
. Chuyển động

Hình: Một Lớp Con người và một Lớp Xe máy

11
3.1.3.4 Bao gói và che giấu thông tin (Encapsulation and Information
Hiding)
Việc đóng gói dữ liệu và các hàm vào một đơn vị cấu trúc (gọi là lớp)
được xem như một nguyên tắc bao gói thông tin. Kỹ thuật này cho phép xác
định các vùng đặc trưng riêng, công khai hay được bảo vệ bao gồm cả dữ liệu
và các câu lệnh nhằm điều khiển hoặc hạn chế những truy nhập tùy tiện của
những đối tượng khác. Đóng gói dữ liệ
u và các hàm vào một đơn vị cấu trúc
(gọi là lớp) được xem như một nguyên tắc bao bọc thông tin. Các hàm thành
phần công khai của lớp sẽ đóng vai trò như là giao diện giữa các đối tượng và
với phần còn lại của hệ thống. Nguyên tắc bao bọc dữ liệu để ngăn cấm sự
truy nhập trực tiếp trong lập trình được gọi là sự che giấu thông tin.


Có thể diễn đạt cơ chế kế thừa như sau:
+ Lớp A kế thừa lớp B sẽ có (không tường minh) tất cả các thuộc
tính, hàm đã được xác định trong B, ở những vùng được phép kế thừa (được
bảo vệ, công khai),
+ Bổ sung thêm một số thuộc tính, hàm để mô tả được đúng các
hành vi c
ủa những đối tượng mà lớp A quản lý.
+ Viết đè (thay đổi hành vi ứng xử) của các hàm được kế thừa.
3.1.3.6 Đa xạ (tương ứng bội) và nạp chồng (Polymorphism and
Overloading).
¾ Đa xạ là kỹ thuật được sử dụng để mô tả khả năng gửi một thông điệp
chung tới nhiều đối tượng mà mỗi đối tượng lạ
i có cách xử lý riêng theo
ngữ cảnh của mình.
13

năng, hàm sẽ không được xác định cho đến khi các lời gọi hàm được
thực hiện theo ngữ cảnh lúc thực hiện.
3.1.3.8 Truyền thông điệp (Message Passing)
Chương trình hướng đối tượng bao gồm một tập các đối tượng và mối
quan hệ giữa các đối tượng đó với nhau. Lập trình trong ngôn ngữ hướng đố
i
tượng bao gồm các bước sau:
9 Tạo ra các lớp đối tượng và mô tả hành vi của chúng,
9 Tạo ra các đối tượng theo định nghĩa của các lớp,
9 Xác định sự trao đổi thông tin giữa các đối tượng trong hệ thống.
Nguyên lý trao đổi thông tin bằng cách truyền thông điệp cho phép
chúng ta dễ dàng xây dựng được hệ thống mô phỏng gần hơn với thực tế.
Truyền thông điệp cho mộ
t đối tượng tức là báo cho nó phải thực hiện một
việc, một yêu cầu (thỉnh cầu) nào đó. Cách ứng xử của đối tượng sẽ được mô
tả ở trong lớp thông qua các hàm công khai (hay còn được gọi là lớp dịch vụ).
Trong chương trình, thông điệp gửi đến cho một đối tượng chính là để
yêu cầu thực hiện một công việc cụ thể, nghĩa là sử dụng những hàm t
ương
ứng để xử lý dữ liệu đã được khai báo trong lớp đối tượng đó.
Ví dụ, khi hệ thống máy tính muốn in một tệp dataFile thì máy tính
hiện thời (:Computer
) gửi đến cho đối tượng :PrinterServer một yêu cầu
Print(dataFile).

thân lớp
}
Trong đó:
Bổ từ truy xuất
Bổ từ truy xuất xác định thành viên (nói tắt của biến thành viên và
phương thức thành viên) nào của lớp được truy xuất từ lớp khác. Có các loại
kiểu truy xuất sau:

Từ khóa Giải thích
public Truy xuất mọi nơi
protected Truy xuất trong nội bộ lớp hoặc trong các lớp con

16
internal Truy xuất nội trong chương trình (assembly)
protected
internal
Truy xuất nội trong chương trình (assembly) và
trong các lớp con.
private( mặc
định)
Chỉ được truy xuất trong nội bộ lớp
Bảng 3.2-1 Các bổ từ truy xuất
Thân lớp
Trong thân lớp là các chức năng được định nghĩa trong lớp như: phương
thức(methods), các thuộc tính(properties), constructor, hay các nạp chồng toán
hạng(Operator Overloads).
Attribute
Một attribute là 1 thứ dùng để đánh dấu (marker) mà được ứng
dụng đến 1 phương thức hay 1 lớp thậm chí là 1 đối số riêng trong 1 phưong
thức ,cung cấp thông tin thêm về mục đó. ví dụ attribute Conditional có thể

xem như obsolete ( không dùng nữa). Tuỳ thuộc vào việc thiết lập trên
attribute này, trình biên dịch sẽ sinh ra 1 cảnh báo hay lỗi nếu nó gặp bất kì
mã nào cố g
ắng dùng phương thức này.
Ví dụ 3.2-1: Khai báo một lớp
public class MyClass
{
public static int Main( )
{

}
}
3.2.1.2 Đối tượng
Khi khai báo một lớp ta định nghĩa các đặc tính chung của tất cả các đối
tượng của lớp và các hành vi của chúng. Object – chỉ đơn giản là một thuật
ngữ chỉ về một thực thể (instance) của một class nào đó trong bộ nhớ. Đối
tượng là mộ
t trị có thể được tạo ra, lưu giữ và sử dụng. Trong C# tất cả các
biến đều là đối tượng. Các biến kiểu số, kiểu chuỗi … đều là đối tượng. Mỗi
một đối tượng đều có các biến thành viên để lưu giữ dữ liệu và có các phương
thức (hàm) để tác động lên biến thành viên. Mỗi đối tượng thuộc về một lớp
đối tượng nào đó. Các đố
i tượng có cùng lớp thì có cùng các biến thành viên
và phương thức.
Tạo một đối tượng bằng cách khai báo kiểu và sau đó dùng từ khoá new
để tạo cú pháp như sau:
<tên kiểu> <tên đối tượng> = new <tên lớp>
Ví dụ 3.2-2: Khai báo, tạo và sử dựng một lớp
using System;
public class Time

}
Sealed các lớp và phương thức:
C# cho phép các lớp và phương thức được khai báo sealed. Nếu là lớp
có nghĩa là bạn không được quyền thừa kế lớp đó, nếu là phương thức tức là
bạn không được phép override nó. C# sử dụng từ khoá sealed trướ
c tên lớp và
phương thức:
sealed class FinalClass
{
//etc
}
class DerivedClass : FinalClass // wrong. Will give compilation error
{
//etc
}
class MyClass

19
{
Public sealed override void FinalMethod()
{
//etc
}
}
Class DerivedClass : MyClass
{
public override void FinalMethod() // wrong. Will give compilation error
{
}
}

void. Phương thức set có thể ghi vào cơ sở dữ liệu hay cập nhật biến thành
viên khi cần. Trong thân set, có biến mặc định là value, biến này sé mang kiểu
đã được khai báo property, như trong trường hợp trên là string. Biến value sé
nhận giá tr
ị được gán cho Property. Thân của phương thức truy cập get cũng
giống như các phương thức khác nhưng phương thức này trả vể một đối tượng
kiểu là một đặc tính của lớp. Cách sử dụng một Property như sau:
1 // trong thân của một hàm
2 DocGia dgMoi = new DocGia();
3
4 // sử dung property set
5 dgMoi.HoTen = "Nguyễn Văn A";
6
7 // sử dụng property get
8 string ten = dgMoi.HoTen; //ten có giá trị "Nguyễn Văn A"
Ở dòng mã thứ 5, khố
i set trong property HoTen sẽ được gọi, biến value
sẽ có giá trị của biến nằm sau phép gán (trong trường hợp này là "Nguyễn Van
A"). Nếu trong thân hàm không cài đặt hàm set, property sẽ có tính chỉ đọc,
phép gán sẽ bị cấm. Ngược lại nếu không cài đặt hàm get, property sẽ có tính
chỉ ghi.
Public string SomeProperty
{
get
{
return “This is the property value”;
}
set
{
// do whatever needs to be done to set the property


chọn tên của nó, nhưng ngược lại trong C# tham số này hoàn toàn giả lập và
luôn mang tên là value.
Thuộc tính chỉ đọc và chỉ viết:
Bạn có thể tạo ra thuộc tính chỉ đọc bằng cách bỏ thủ tục set trong khai
báo và tạo ra thuộc tính chỉ ghi bằng cách bỏ thủ tục get trong khai bao thuộc
tính đó. Ví dụ để định nghĩa thuộc tính Forename là chỉ đọc:
private string foreName;
public string
ForeName
{
get
{
return foreName;
}
}
Bổ từ truy cập:

22
C# không cho phép cài đặt những bổ từ khác nhau cho thủ tục set và
get. Nếu bạn muốn tạo ra một thuộc tính có public để đọc nhưng lại muốn hạn
chế protected trong gán thì đầu tiên bạn phải tạo thuộc tính chỉ đọc với bổ từ
public sau đó tạo một hàm set() với bổ từ protected ở bên ngoài thuộc tính đó.
public string ForeName
{
get
{
return foreName;
}
}

// public accessor methods
public void DisplayCurrentTime()
{
Console.WriteLine("Time\t: {0}/{1}/{2} {3}:{4}:{5}",
month, date, year, hour, minute, second);
Console.ReadLine();
}
// constructors
public Time(System.DateTime dt)
{
year = dt.Year;
month = dt.Month;
date = dt.Day;
hour = dt.Hour;
minute = dt.Minute;
second = dt.Second;
}
// tạo một đặc tính
public int Hour
{
get { return hour; }
set { hour = value; }
}
// các biến thành viên kiểu private
private int year;
private int month;
private int date;
private int hour;
private int minute;
private int

như thế nào? Thông thường một phương thức là một tên của hành động.ví dụ
WriteLine. Tuy nhiên chúng cũng có thể là các tên đặc biệ
t như Main().
9 Khai báo phương thức là một liên lạc giữa người tạo và sử dụng
phương thức.
9 Để khai báo một phương thức chúng ta cần chỉ ra kiểu giá trị về
theo sau bởi tên. Một phương thức có thể có tham số hay không.
[thành phần khai báo]<giá trị trả về><tên phương thức>(tham số)
{
//than phuong thuc
}
Thành phần khai báo là các từ khóa: public,static,abstract,private…
Giá trị trả về là kiểu dữ liệu mà ta có thể
cho phương thức đó trả về. Nếu
phương thức khônng có kiểu trả về ta sử dung từ khóa void.

25
Các thành phần khai báo public được sử dụng bên trong và bên ngoài của lớp
+ Các thuộc tính thường được khai báo là private đã được bảo vệ an toàn
dữ liệu
+ Các phương thức thường được khai báo public để chúng có thể gọi đến
các hàm trong chương trình
+ Còn hàm thành phần protected cũng giống hàm private chỉ khác là
protected có thể truy nhập được từ định nghĩa các hàm dẫn xuất
+ abstract:- abstract có thể dùng để định nghĩa Method : bắt buộc phả
i
override ở subclass. Method này chỉ định nghĩa mà không viết đầy đủ
thân.Nếu trong class có một phương thức abstract thì class đó buộc phải là
abstract
+ static: Method và Variable : được truy xuất trực tiệp thông qua tên class


Nhờ tải bản gốc
Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status