Lập trình hướng đối tượng: Lớp và đối tượng

Ngày đăng: 26 - 02 - 2021 Lượt xem: 422 lượt

Trong lập trình hướng đối tượng, chúng ta sẽ làm quen với 2 khái niệm class (lớp) và object (đối tượng). Có thể nói, lớp là 1 bản thiết kế các thuộc tính và phương thức của đối tượng. Còn đối tượng là sự thể hiện của các lớp, có thuộc tính và hành vi cụ thể. Trong bài viết này chúng ta sẽ không quá tập trung vào các khái niệm mà sẽ học cách sử dụng class và object.

Lập trình hướng đối tượng phần 1 class và object

Khai báo lớp

Để khai báo 1 lớp, ta sử dụng từ khóa class. Cú pháp như sau:

public class Student
{
    //thuộc tính (properties)
    public int StudentId { get; set; }
    public string StudentName { get; set; }

    //hàm dựng (constructor)
    public Student() { }

    public Student(int id)
    {
        this.StudentId = id;
    }

    public Student(int id, string name)
        : this(id)
    {
        this.StudentName = name;
    }

    //phương thức (method)
    public void Show()
    {
        Console.WriteLine("Id {0} - Name: {1}", this.StudentId, this.StudentName);
    }
}

Phân tích đoạn lệnh trên, ta có 1 số vấn đề sau:

  1. Tên class: sử dụng chuẩn Camel (xem thêm chuẩn này ở bài sau: https://hocdotnet.com/kieu-du-lieu-va-bien-trong-c)
  2. Thuộc tính: là các biến lưu giữ các giá trị của 1 đối tượng. Thuộc tính được khai báo kèm với từ khóa get (đọc) và set (ghi) dữ liệu.
  3. Hàm dựng: là 1 hàm đặc biệt, cùng tên với và không có kiểu trả về hay từ khóa void. Hàm dựng có thể overload. Và gọi lại hàm dựng khác thông qua từ khóa this().
  4. Phương thức: phương thức trong lớp hoàn toàn giống như các bài trước ta đã biết. Các bạn có thể đọc thêm tại https://hocdotnet.com/phuong-thuc-va-cac-tham-so-bo-tro

Như vậy, khai báo 1 lớp cần đầy đủ các thành phần trên. Tuy nhiên, phương thức của 1 class không cần “cố gắng” cài đặt tất cả, chúng ta chỉ cài đặt khi có nhu cầu sử dụng.

Để thêm 1 class, ta thực hiện như hình sau:

Khai báo đối tượng

Sau khi khai báo class, ta sử dụng từ khóa new để khởi tạo 1 đối tượng của class như sau:

static void Main(string[] args)
{
    //sử dụng hàm dựng không tham số
    Student student = new Student();

    //sử dụng hàm dựng có 1 tham số
    Student student1 = new Student(1);

    //sử dụng hàm dựng có 2 tham số
    Student student2 = new Student(2, "Ray Light");

    Console.ReadKey();
}

Cùng phân tích đoạn code trên, ta nhận thấy các vấn đề sau:

  1. Tên đối tượng là tên biến: student, student1, student2
  2. Từ khóa Student trước tên đối tượng là kiểu dữ liệu, cũng là tên của Lớp.
  3. Từ khóa new là từ khóa để khởi tạo hay còn gọi là cấp phát bộ nhớ cho biến.
  4. Hàm dựng Student(), Student(1), Student(2, “Ray Light”): là các hàm dựng tương ứng của Lớp mà ta đã cài đặt ở trên.

Thông qua ví dụ trên, ta có thể thấy khai báo 1 lớp và đối tượng khá đơn giản. Mục đích của lớp hay đối tượng đó chính là sự kế thừa, tái sử dụng mã nguồn đã có. Và hơn nữa, các bạn có thể tìm kiếm 1 thuật ngữ “DON’T REPEAT YOURSELF” để rõ hơn.

Mối quan hệ “has-a”

Ở ví dụ trên, ta mới khai báo 1 lớp để thể hiện các thông tin của 1 sinh viên. Trong thực tế, chúng ta cần phải khai báo nhiêu lớp hơn nữa để phần mềm có thể chạy “ngon”, và đầy đủ các nghiệp vụ. Để thực hiện được việc này, ta cần nắm bắt khái niệm has-a, mà có thể hiểu đơn giản là sự liên kết giữa các class với nhau.

Ví dụ: Ta có lớp “Khóa học – Course” có nhiều sinh viên thì ta sẽ khai báo như sau:

public class Course
{
    //thuộc tính mảng sinh viên
    public Student[] Students { get; set; }

    //hàm dựng
    public Course()
    {
        //khởi tạo mảng sinh viên
        this.Students = new Student[100];
    }
}

Có thể nói Course “has-a” Student. Trong lớp Course, ta có thể khởi tạo các đối tượng Student, gọi phương thức Show() của mỗi student…

Ta lại có 1 ví dụ khác, ta cần so sánh điểm của trung bình 3 môn của 2 sinh viên. Lúc này, ta sẽ điều chỉnh mã nguồn lớp Student như sau:

public class Student
{
    //thuộc tính (properties)
    public int StudentId { get; set; }
    public string StudentName { get; set; }

    //bổ sung thuộc tính điểm 3 môn
    public float Point1 { get; set; }
    public float Point2 { get; set; }
    public float Point3 { get; set; }

    //hàm dựng (constructor)
    public Student() { }

    public Student(int id)
    {
        this.StudentId = id;
    }

    public Student(int id, string name)
        : this(id)
    {
        this.StudentName = name;
    }

    //phương thức (method)
    public void Show()
    {
        Console.WriteLine("Id {0} - Name: {1}", this.StudentId, this.StudentName);
    }

    //bổ sung hàm tính điểm trung bình của 1 sinh viên
    public float AvgPoint()
    {
        return (Point1 + Point2 + Point3) / 3;
    }
}

Sau đó, trong lớp Student, ta cài đặt hàm so sánh điểm của 2 sinh viên như sau:

public class Student
    {
        ...
        //hàm so sánh điểm giữa 2 sinh viên
        public int CompareTo(Student another)
        {
            if(this.AvgPoint() > another.AvgPoint())
            {
                return 1;
            }    
            else if(this.AvgPoint() < another.AvgPoint())
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
        ...
}

Hàm CompareTo chính là sự khác biệt giữa lập trình hướng đối tượng và lập trình hướng cấu trúc. Tham số hàm CompareTo là 1 đối tượng Student. Điều này nếu trong lập trình hướng cấu trúc, các bạn sẽ viết 1 hàm có 3 tham số (điểm 3 môn của sinh viên cần so sánh) hoặc 6 tham số (tương ứng điểm 3 môn của 2 sinh viên).

Quay lại hàm Main, ta code đoạn lệnh sau để sử dụng hàm CompareTo:

//gán giá trị cho thuộc tính
student.Point1 = 7;
student.Point2 = 8;
student.Point3 = 7;

student1.Point1 = 8;
student1.Point2 = 8;
student1.Point3 = 6;

//so sánh điểm 2 sinh viên
int compared = student.CompareTo(student1);

Như vậy, ta có thể thấy, logic của hướng đối tượng để thể hiện đầy đủ trong hàm CompareTo. Nắm vững các khai báo và sử dụng này, các bạn có thể triển khai mạch lạc các class trong tương lai lập trình của mình.

Lớp trừu tượng

Lớp trừu tượng hay còn gọi là Abstract Class là 1 lớp chứa các phương thức chưa được triển khai hoặc kế thừa 1 lớp trừu tượng khác nhưng không triển khai các phương thức của lớp cha.

Phương thức chưa được triển khai là phương thức chỉ khai báo: kiểu trả về, tên phương thức, tham số mà không có {//code block}

Ví dụ:

//khai báo lớp trừu tượng
public abstract class Animal
{
    public int Id { get; set; }
    public int Name { get; set; }

    //phương thức trừu tượng
    public abstract void Voice();
}

Qua ví dụ trên, ta thấy lớp trừu tượng Animal được khai báo kèm từ khóa abstract. Ngoài ra, trong lớp trừu tượng có 1 hàm Voice cũng đi kèm từ khóa này. Và hàm Voice này chỉ khai báo tên mà không có mã nguồn cài đặt.

Sử dụng lớp trừu tượng

Vậy lớp trừu tượng dùng để làm gì?

Trong nội dung trên, ta có 1 thuật ngữ “don’t repeat yourself”, lớp trừu tượng được sinh ra để hỗ trợ việc này. Tức là, có những lớp sẽ trùng lặp các thuộc tính hoặc phương thức. Để loại bỏ việc này, ta tạo 1 lớp trừu tượng có các thành phần chung, sau đó cho lớp khác kế thừa.

Ví dụ ta xây dựng lớp Cat kế thừa lớp Animal như sau:

public class Cat : Animal
{
    public override void Voice()
    {
        Console.WriteLine("This is a voice of " + base.Name);

        Console.WriteLine("MEO MEO MEO");
    }
}

Ở ví dụ này, ta thấy xuất hiện từ khóa override. Từ khóa này thể hiện việc cài đặt phương thức abstract Voice của lớp Animal. Ngoài ra, ta dùng từ khóa base để truy xuất các thuộc tính của lớp Animal.

Các ví dụ sâu hơn về kế thừa sẽ được trình bày ở phần kế thừa và đa hình.

Bài tập củng cố:

1. Bài 1: Tạo một lớp phân số có tử số và mẫu số. Yêu cầu
• Khai báo lớp Phân số
• Cài đặt các constructor
• Viết hàm cộng 2 phân số

Bài 2: Tạo 1 lớp Point, có 2 thuộc tính là tọa độ Ox và Oy.
Yêu cầu:
• Khai báo lớp Point
• Cài đặt các constructor
• Viết hàm tính khoản cách giữa 2 Point

Bài 3: Sử dụng lớp Point đã có ở bài tập 2 để xây dựng lớp Circle có tâm Center là 1 Point và bán kính Radius.
Yêu cầu
– viết lớp Circle
– viết các constructors
– viết hàm nhập 1 Circle
– viết hàm kiểm tra 1 điểm bất kỳ nằm TRÊN, TRONG hay NGOÀI đường tròn.

5 1 vote
Article Rating

Subscribe
Notify of
guest
23 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
HuynhVanDong-17C1

class Program     {         static void Main(string[] args)         {             // b1             PhanSo phanSo1 = new PhanSo(1,2);             PhanSo phanSo2 = new PhanSo(1,2);             string congHaiPhanSo = phanSo1.SumTo(phanSo2);             Console.WriteLine(congHaiPhanSo);             // b2             Point point1 = new Point(1,2);             Point point2 = new Point(5,3);             double distance = point1.distance(point2);             Console.WriteLine(distance);             // b3             Circle circle = new Circle();             circle.InputData();             Point point = new Point(3,4);             Console.WriteLine(circle.checkArea(point));         }     } public class PhanSo     {         public int TuSo {get; set;}         public int MauSo {get; set;}         public PhanSo() {}         public PhanSo(int tuSo, int mauSo)         {             this.TuSo = tuSo;             this.MauSo = mauSo;         }            public string SumTo(PhanSo another)         {             int mauSo = this.MauSo * another.MauSo;             int tuSo = (this.TuSo * another.MauSo) + (this.MauSo * another.TuSo);                          if(tuSo/UCLN(tuSo,mauSo) == mauSo/UCLN(tuSo,mauSo))             {                 return 1 + "";             }             return tuSo/UCLN(tuSo,mauSo) + "/" + mauSo/UCLN(tuSo,mauSo);         }         private int UCLN(int a, int b) {             int tmp;             while(b != 0) {                 tmp = a % b;                 a = b;                 b = tmp;             }             return a;… Read more »

Nguyen Van Cam - 17CNTT1

class Program   {     static void Main(string[] args)     {       //b1       Phanso phanSo1 = new Phanso(1, 3);       Phanso phanSo2 = new Phanso(1, 3);       Console.WriteLine(phanSo1.Sum(phanSo2));       //b2       Point point1 = new Point(1, 3);       Point point2 = new Point(4, 3);       Console.WriteLine(point1.distance(point2));       //b3       Circle circle = new Circle();       circle.Input();       Point point = new Point(5, 4);       Console.WriteLine(circle.checkArea(point));… Read more »

phan thanh hoang long-18cntt4

1. class Fraction   {     public int TuSo { get; set; }     public int MauSo { get; set; }     public Fraction() { }     public Fraction(int tuSo,int mauSo)     {       this.TuSo = tuSo;       this.MauSo = mauSo;     }     public void Add(Fraction fraction)     {       int tuSo=TuSo*fraction.MauSo+MauSo*fraction.TuSo, mauSo=MauSo*fraction.MauSo;       for(int i = tuSo > mauSo ? mauSo… Read more »

phan thanh hoang long-18cntt4

xin test sai thay

Đào Ngọc Khuê

using System; namespace object_class {   class Program   {     static void Main(string[] args)     {       Console.WriteLine(“Tong 2 Phan So!”);       PhanSo ps = new PhanSo(5, 6, 7, 8);       ps.Sum();       Console.WriteLine(“Tinh Khong Cach 2 diem”);       Point p = new Point(1, 2, 3, 4);               Console.WriteLine(“Khoang Cach La:”+p.Distance(p.x1,p.y1,p.x2,p.y2));       Console.WriteLine(“Duong tron”);       Console.WriteLine(“Nhap Tam Duong Tron:”);       int… Read more »

Mai Huỳnh Lộc - 16CNTT2

using System; namespace C_ { class Program { static void Main(string[] args) { //Bai tap 1 /*PhanSo ps1 = new PhanSo(); ps1.Nhap(); PhanSo ps2 = new PhanSo(1,1); ps2.Nhap(); PhanSo ps3 = ps1 + ps2; ps3.Xuat();*/ //Bai tap 2 Point a = new Point(); a.Nhap(); Point b = new Point(1,1); b.Nhap();… Read more »

TranThiNho-18CD

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HuongDoiTuong {   class Program   {     static void Main(string[] args)     {       //bai1       PhanSo phanSo1 = new PhanSo();       PhanSo phanSo2 = new PhanSo();       Console.WriteLine(“Nhap phan so 1:”);       phanSo1.nhapPS();       Console.WriteLine(“Nhap phan so 2:”);       phanSo2.nhapPS();       double tong = phanSo1.tongPS(phanSo2);       Console.WriteLine(tong);       //bai2       Point point1… Read more »

Võ Thị Mỹ Loan 18CNTT1

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BT4 {   class Program   {     static void Main(string[] args)     {       //1       PhanSo ps1 = new PhanSo(1, 2);       PhanSo ps2 = new PhanSo(2, 3);       ps1.Tong(ps2);       //2       Point pt1 = new Point(0, 0);       Point pt2 = new Point(0, 3);       Console.WriteLine(“Khoang cach… Read more »

Thuong Thi Thu Hiep

class Program   {     static void Main(string[] args)     {    //bai1:        PhanSo ps1 = new PhanSo();       PhanSo ps2 = new PhanSo();       PhanSo Tongps = ps1 + ps2;       Console.WriteLine(“Tong 2 phan so la: “,Tongps);        //bai2          public class Point1        {         public float x1 { set; get; }         public float y1 { set; get;… Read more »

Dao Thi Que Anh-18CNTT1

class Phanso   {     public int TuSo { get; set; }     private int mauSo;     public int MauSo      {        get { return mauSo; }       set        {         mauSo = value;         if (mauSo < 0)         {           TuSo = -TuSo;           mauSo = -mauSo;         }       }     }     public Phanso(int ts,int ms)     {       if(ms < 0)       {… Read more »

Nguyen Le Cong Nguyen - 18CNTT4

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test {   class Program   {     static void Main(string[] args)     {               Console.WriteLine(“Tong cua hai phan so la: “);       PhanSo ps = new PhanSo(2, 5, 9, 4);       Console.WriteLine(“Tinh khoang cach giua 2 diem la: “);       Point p = new Point(2,… Read more »

Dao Thi Que Anh-18CNTT1

class Phanso   {     public int TuSo { get; set; }     public int MauSo { get; set; }     public Phanso(int ts,int ms)     {             TuSo = ts;       MauSo = ms;     }           private int UCLN(int a,int b)     {       int tmp;       while(b != 0)       {         tmp = a % b;         a = b;… Read more »

Phạm Văn Lợi

//Bài 1  class FRACTION   {     public int tu { get; set; }     public int mau { get; set; }     public FRACTION() { }     public FRACTION(int tuso,int mauso)     {       this.tu=tuso;       this.mau=mauso;     }     public int USCLN(int a, int b)     {       int temp;       while (b > 0)       {         a = a % b;… Read more »

ĐOÀN THỊ THU 18CNTT4

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BTlop_doituong {   /* Câu1: Tạo một lớp phân số có tử số và mẫu số. Yêu cầu – Khai báo lớp phân số – Cài đặt các constructor – Viết hàm cộng 2 phân số    */       class PHANSO… Read more »

LuuKimHoang-18CNTT4

class PhanSo   {     public int Tu { get; set; }     public int Mau { get; set; }     public PhanSo() { }     public PhanSo(int Tu, int Mau)     {       this.Tu = Tu;       this.Mau = Mau;     }        public string Sum(PhanSo phanso)     {       int tu = this.Tu*phanso.Mau+ phanso.Tu*this.Mau;       int mau = this.Mau *… Read more »

LyHuuPhuc-18CNTT2

using System; namespace ConsoleApp2 {   class Program   {     public class PhanSo     {       public int TuSo { get; set; }       public int MauSo { get; set; }       public PhanSo() { }       public PhanSo(int TuSo, int Mauso)       {         this.TuSo = TuSo;         this.MauSo = Mauso;       }       public String SumToPhanSo(PhanSo another)       {         int tuso… Read more »

Lê Văn Thắng 16CNTT2

using System; namespace Baitap_tuan_4 {   class Program   {     static void Main(string[] args)     {       Fraction firstFraction = new Fraction(1, 4);       Fraction secondFraction = new Fraction(1, 2);       Console.WriteLine(firstFraction.Sum(secondFraction));       Point firstPoint = new Point(1, 3);       Point secondPoint = new Point(4, 3);       Console.WriteLine(firstPoint.distance(secondPoint));       Point point = new Point(5, 4);       Point thirdPoint = new Point(5,… Read more »

DangBaLoc-18cntt3

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace csl1 {   /* 1 */   class PHANSO   {     public int tu { get; set; }     public int mau { get; set; }     public PHANSO() { }     public PHANSO(int tuso, int mauso)     {       this.tu = tuso;       this.mau = mauso;     }… Read more »

Phạm Thị Thùy_18CNTT3

class Phanso   {     public int TuSo { get; set; }     public int MauSo { get; set; }     public Phanso(int ts,int ms)     {             TuSo = ts;       MauSo = ms;     }           private int UCLN(int a,int b)     {       int tmp;       while(b != 0)       {         tmp = a % b;         a = b;… Read more »

Bài viết liên quan

23
0
Would love your thoughts, please comment.x
()
x