JavaRush /Blog Java /Random-VI /Nguyên tắc OOP

Nguyên tắc OOP

Xuất bản trong nhóm
Xin chào! Bạn có bao giờ thắc mắc tại sao Java lại được thiết kế như vậy không? Theo nghĩa là bạn tạo các lớp, dựa trên chúng - các đối tượng, các lớp có các phương thức, v.v. Nhưng tại sao cấu trúc của ngôn ngữ lại sao cho các chương trình bao gồm các lớp và đối tượng chứ không phải thứ gì khác? Tại sao khái niệm “vật thể” được phát minh và đặt lên hàng đầu? Có phải tất cả các ngôn ngữ đều hoạt động theo cách này và nếu không, nó mang lại lợi ích gì cho Java? Như bạn có thể thấy, có rất nhiều câu hỏi :) Hãy thử trả lời từng câu hỏi trong bài giảng hôm nay.

Nguyên tắc OOP:

  1. Di sản
  2. Trừu tượng
  3. Đóng gói
  4. Đa hình

Lập trình hướng đối tượng (OOP) là gì

Tất nhiên, Java được tạo thành từ các đối tượng và các lớp là có lý do. Đây không phải là ý tưởng bất chợt của những người sáng tạo ra nó, hay thậm chí là phát minh của họ. Có nhiều ngôn ngữ khác dựa trên đối tượng. Ngôn ngữ đầu tiên như vậy được gọi là Simula và nó được phát minh vào những năm 1960 ở Na Uy. Trong số những thứ khác, Simula đã giới thiệu các khái niệm về “ lớp ” và “ phương pháp ”. Nguyên lý lập trình hướng đối tượng - 2
Kristen Nygaard và Ole Johan Dahl - người tạo ra Simula
Có vẻ như Simula là một ngôn ngữ cổ xưa theo tiêu chuẩn lập trình, nhưng mối liên hệ “gia đình” của chúng với Java có thể nhìn thấy bằng mắt thường. Rất có thể, bạn có thể dễ dàng đọc mã được viết trên đó và giải thích một cách chung chung về chức năng của nó :)
Begin
  Class Rectangle (Width, Height); Real Width, Height;

   Begin
      Real Area, Perimeter;

      Procedure Update;
      Begin
        Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
        Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
      End of Update;

      Update;
      OutText("Rectangle created: "); OutFix(Width,2,6);
      OutFix(Height,2,6); OutImage;
   End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;

  Begin
      OutText("ColouredRectangle created, color = "); OutText(Color);
      OutImage;
        End of ColouredRectangle;


         Ref(Rectangle) Cr;
   Cr :- New ColouredRectangle(10, 20, "Green");
End;
Ví dụ mã được lấy từ bài viết Simula - 50 năm OOP . Như bạn có thể thấy, Java và tổ tiên của nó không quá khác biệt với nhau :) Điều này là do sự xuất hiện của Simula đánh dấu sự ra đời của một khái niệm mới - lập trình hướng đối tượng. Wikipedia đưa ra định nghĩa sau về OOP: Lập trình hướng đối tượng (OOP) là một phương pháp lập trình dựa trên việc biểu diễn một chương trình dưới dạng một tập hợp các đối tượng, mỗi đối tượng là một thể hiện của một lớp cụ thể và các lớp tạo thành một hệ thống phân cấp kế thừa. Theo tôi, nó rất thành công. Gần đây bạn đã bắt đầu học Java, nhưng hầu như không có từ nào trong đó là xa lạ với bạn :) Ngày nay, OOP là phương pháp lập trình phổ biến nhất. Bên cạnh Java, nguyên tắc OOP được sử dụng trong nhiều ngôn ngữ phổ biến mà có thể bạn đã từng nghe tới. Đó là C++ (được các nhà phát triển trò chơi máy tính sử dụng tích cực), Objective-C và Swift (họ viết chương trình cho thiết bị Apple), Python (có nhu cầu cao nhất trong học máy), PHP (một trong những ngôn ngữ phát triển web phổ biến nhất), JavaScript (nói đơn giản hơn là họ không làm gì với nó) và nhiều thứ khác. Thực ra, những “nguyên tắc” này của OOP là gì? Hãy cho bạn biết chi tiết hơn.

Nguyên tắc OOP

Đây là điều cơ bản. 4 tính năng chính cùng nhau tạo thành mô hình lập trình hướng đối tượng. Hiểu chúng là chìa khóa để trở thành một lập trình viên thành công. Nguyên lý lập trình hướng đối tượng - 3

Nguyên tắc 1. Kế thừa

Tin vui là bạn đã quen với một số nguyên tắc của OOP! :) Chúng tôi đã gặp phải tính kế thừa một vài lần trong các bài giảng và chúng tôi đã có thời gian làm việc với nó. Kế thừa là một cơ chế cho phép bạn mô tả một lớp mới dựa trên lớp (cha mẹ) hiện có. Trong trường hợp này, các thuộc tính và chức năng của lớp cha được lớp mới mượn. Tại sao việc thừa kế là cần thiết và nó mang lại lợi ích gì? Trước hết, tái sử dụng mã. Các trường và phương thức được mô tả trong lớp cha có thể được sử dụng trong các lớp con. Nếu tất cả các loại ô tô đều có 10 trường chung và 5 phương thức giống nhau thì bạn chỉ cần đặt chúng vào lớp cha Auto. Bạn có thể sử dụng chúng trong các lớp con cháu mà không gặp vấn đề gì. Ưu điểm vững chắc: cả về mặt định lượng (ít mã hơn) và kết quả là về mặt chất lượng (các lớp trở nên đơn giản hơn nhiều). Đồng thời, cơ chế kế thừa rất linh hoạt và bạn có thể thêm riêng chức năng còn thiếu vào phần con (một số trường hoặc hành vi cụ thể cho một lớp cụ thể). Nói chung, cũng như trong cuộc sống đời thường: tất cả chúng ta đều giống cha mẹ mình ở một số điểm, nhưng khác với họ ở một số điểm :)

Nguyên tắc 2. Trừu tượng hóa

Đây là một nguyên tắc rất đơn giản. Trừu tượng hóa có nghĩa là làm nổi bật những đặc điểm chính, quan trọng nhất của một đối tượng và ngược lại - loại bỏ những đặc điểm phụ, không quan trọng. Chúng ta đừng phát minh lại bánh xe và nhớ lại một ví dụ từ một bài giảng cũ về các lớp học. Giả sử chúng ta đang tạo một tủ hồ sơ gồm các nhân viên của công ty. Để tạo các đối tượng nhân viên, chúng tôi đã viết một lớp Employee. Những đặc điểm nào là quan trọng đối với mô tả của họ trong hồ sơ công ty? Họ tên, ngày sinh, số an sinh xã hội, mã số thuế. Nhưng không chắc trong một tấm thẻ loại này, chúng ta cần có chiều cao, màu mắt và màu tóc của anh ấy. Công ty không cần thông tin này về nhân viên. Do đó, đối với lớp, Employeechúng ta sẽ đặt các biến String name, int age, int socialInsuranceNumberint taxNumber, và chúng ta sẽ loại bỏ những thông tin không cần thiết đối với chúng ta, chẳng hạn như màu mắt và trừu tượng hóa nó. Nhưng nếu chúng ta tạo một danh mục người mẫu ảnh cho một đại lý thì tình hình sẽ thay đổi đáng kể. Để mô tả một người mẫu thời trang, chiều cao, màu mắt và màu tóc rất quan trọng đối với chúng ta nhưng không cần đến số TIN. Vì vậy, trong lớp Modelchúng ta tạo các biến String height, String hair, String eyes.

Nguyên tắc 3: Đóng gói

Chúng tôi đã gặp phải nó rồi. Đóng gói trong Java có nghĩa là hạn chế quyền truy cập vào dữ liệu và khả năng thay đổi dữ liệu đó. Như bạn có thể thấy, nó dựa trên từ “viên nang”. Trong “viên nang” này, chúng tôi ẩn một số dữ liệu quan trọng mà chúng tôi không muốn bất kỳ ai thay đổi. Một ví dụ đơn giản từ cuộc sống. Bạn có họ và tên. Mọi người bạn biết đều biết họ. Nhưng họ không có quyền thay đổi họ và tên của bạn. Người ta có thể nói, quá trình này được “đóng gói” trong văn phòng hộ chiếu: bạn chỉ có thể thay đổi họ và tên của mình ở đó và chỉ bạn mới có thể làm điều đó. Những “người dùng” khác có quyền truy cập chỉ đọc vào họ và tên của bạn :) Một ví dụ khác là số tiền trong căn hộ của bạn. Để chúng ở nơi dễ thấy ở giữa phòng không phải là một ý kiến ​​hay. Bất kỳ “người dùng” nào (người đến nhà bạn) đều có thể thay đổi số tiền của bạn, tức là. nhặt chúng lên. Tốt hơn là nên gói chúng trong két sắt. Chỉ bạn mới có quyền truy cập và chỉ với một mã đặc biệt. Các ví dụ rõ ràng về đóng gói mà bạn đã làm việc là các công cụ sửa đổi truy cập ( private, publicv.v.) và getter-setters. Nếu trường agelớp Catkhông được đóng gói, bất kỳ ai cũng có thể viết:
Cat.age = -1000;
Và cơ chế đóng gói cho phép chúng ta bảo vệ trường agebằng phương thức setter, trong đó chúng ta có thể kiểm tra xem tuổi không thể là số âm.

Nguyên tắc 4. Đa hình

Đa hình là khả năng xử lý nhiều loại như thể chúng là cùng một loại. Trong trường hợp này, hành vi của các đối tượng sẽ khác nhau tùy thuộc vào loại mà chúng thuộc về. Nghe có vẻ hơi phức tạp? Hãy tìm ra nó ngay bây giờ. Hãy lấy ví dụ đơn giản nhất - động vật. Hãy tạo một lớp Animalvới một phương thức duy nhất - voice(), và hai lớp con của nó - CatDog.
public class Animal {

   public void voice() {

       System.out.println("Voice!");
   }
}

public class Dog extends Animal {


   @Override
   public void voice() {
       System.out.println("Bow-wow!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}
Bây giờ hãy thử tạo một liên kết Animalvà gán cho nó một đối tượng Dog.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.voice();
   }
}
Bạn nghĩ phương pháp nào sẽ được gọi? Animal.voice()hoặc Dog.voice()? Phương thức lớp sẽ được gọi là Dog: Woof-woof! Chúng tôi đã tạo một tham chiếu Animalnhưng đối tượng hoạt động như Dog. Nếu cần, anh ta có thể cư xử như một con mèo, một con ngựa hoặc một con vật khác. Điều chính là gán một tham chiếu kiểu chung Animalcho một đối tượng của một lớp con cụ thể. Điều này hợp lý vì tất cả chó đều là động vật. Đây chính là ý của chúng tôi khi nói “các đối tượng sẽ hoạt động khác nhau tùy thuộc vào loại của chúng”. Nếu chúng ta tạo một đối tượng Cat
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.voice();
}
phương thức voice()sẽ xuất ra "Meo meo!" “Khả năng làm việc với nhiều loại như thể chúng cùng loại” nghĩa là gì? Điều này cũng khá dễ dàng. Hãy tưởng tượng rằng chúng ta đang tạo một tiệm làm tóc cho động vật. Tiệm làm tóc của chúng tôi phải có khả năng cắt tất cả các con vật, vì vậy chúng tôi sẽ tạo một phương thức shear()(“cắt”) với một tham số Animal- con vật mà chúng tôi sẽ cắt.
public class AnimalBarbershop {

   public void shear(Animal animal) {

       System.out.println("The haircut is ready!");
   }
}
Và bây giờ chúng ta có thể truyền shearcả đối tượng Catvà đối tượng cho phương thức Dog!
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.shear(cat);
   barbershop.shear(dog);
}
Đây là một ví dụ rõ ràng: lớp AnimalBarbershoplàm việc với các kiểu Catnhư Dogthể chúng là cùng một kiểu. Đồng thời, họ có những hành vi Catkhác nhau Dog: họ sử dụng giọng nói của mình một cách khác nhau.

Lý do cho sự xuất hiện của OOP

Tại sao khái niệm lập trình mới này - OOP - lại xuất hiện ? Các lập trình viên đã có những công cụ hoạt động: ví dụ như ngôn ngữ thủ tục. Điều gì đã thúc đẩy họ phát minh ra thứ gì đó mới mẻ về cơ bản? Trước hết là sự phức tạp của các nhiệm vụ mà họ phải đối mặt. Nếu 60 năm trước, nhiệm vụ của một lập trình viên giống như “tính toán một phương trình toán học thế này thế nọ” thì bây giờ nó có vẻ giống như “thực hiện 7 kết thúc khác nhau cho trò chơi STALKER tùy thuộc vào quyết định của người dùng trong các khoảnh khắc trò chơi A, B, C, D”. , E, F và sự kết hợp của các giải pháp này.” Các nhiệm vụ, như bạn có thể thấy, rõ ràng đã trở nên phức tạp hơn trong những thập kỷ qua. Điều này có nghĩa là các kiểu dữ liệu đã trở nên phức tạp hơn. Đây là một lý do khác cho sự xuất hiện của OOP. Ví dụ với phương trình có thể được giải dễ dàng bằng cách sử dụng các nguyên hàm thông thường; không cần có đối tượng nào ở đây. Nhưng sẽ rất khó để mô tả vấn đề ở phần kết của trò chơi nếu không sử dụng một số lớp mà bạn đã phát minh ra. Nhưng đồng thời, khá dễ dàng để mô tả nó trong các lớp và đối tượng: rõ ràng là chúng ta sẽ cần lớp Game, lớp Stalker, lớp Ending, lớp Quyết định của người chơi, lớp Game Moment, v.v. Nghĩa là, ngay cả khi chưa bắt đầu giải quyết một vấn đề, chúng ta vẫn có thể dễ dàng tưởng tượng ra “bản phác thảo” về giải pháp của nó trong đầu. Sự phức tạp ngày càng tăng của các vấn đề đã buộc các lập trình viên phải chia vấn đề thành nhiều phần. Nhưng trong lập trình thủ tục, điều này không dễ dàng như vậy. Và rất thường xuyên, chương trình là một “cái cây” gồm nhiều nhánh với tất cả các phương án có thể có cho hoạt động của nó. Tùy thuộc vào các điều kiện nhất định, chương trình được thực hiện dọc theo nhánh này hay nhánh khác. Đối với các chương trình nhỏ, tùy chọn này thuận tiện nhưng rất khó chia một nhiệm vụ lớn thành nhiều phần. Nhu cầu này đã trở thành một lý do khác cho sự xuất hiện của OOP. Khái niệm này mang lại cho các lập trình viên khả năng chia chương trình thành nhiều “mô-đun” lớp, mỗi lớp thực hiện một phần công việc riêng. Tất cả các đối tượng tương tác với nhau tạo thành công việc của chương trình của chúng ta. Ngoài ra, mã chúng ta viết có thể được sử dụng lại ở nơi khác trong chương trình, điều này cũng giúp tiết kiệm rất nhiều thời gian.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION