Làm cách nào tôi có thể giải thích lập trình hướng đối tượng cho ai đó chỉ được mã hóa trong Fortran 77?


11

Mẹ tôi đã làm luận án đại học ở Fortran, và bây giờ (hơn một thập kỷ sau) cần học c ++ để mô phỏng chất lỏng. Cô ấy có thể hiểu tất cả các chương trình thủ tục, nhưng cho dù tôi có cố gắng giải thích các đối tượng với cô ấy như thế nào, thì nó cũng không dính vào. (Tôi làm việc rất nhiều với Java, vì vậy tôi biết các đối tượng hoạt động như thế nào) Tôi nghĩ rằng tôi có thể giải thích nó theo những cách quá cao cấp, vì vậy nó không thực sự có ý nghĩa với một người không bao giờ làm việc với họ và phát triển trong thời đại lập trình thủ tục đơn thuần.

Có cách nào đơn giản để tôi có thể giải thích chúng cho cô ấy sẽ giúp cô ấy hiểu không?


2
Bạn có thể xây dựng một ngôi nhà chim mà không trở thành một thợ mộc. Có lẽ cô ấy có thể bắt đầu dự án thực hiện theo cách của cô ấy / thủ tục và bạn có thể chỉ cho cô ấy cách tái cấu trúc theo cách OOP. Đôi khi không phải là "Tôi không nhận được OOP" mà là "Tôi không hiểu tại sao bạn gặp phải tất cả những rắc rối đó"
JeffO

4
Cô ấy thực sự cần phải tự lập trình hướng đối tượng, hay liệu có đủ để sử dụng OpenFOAM theo cách thức thủ tục không?
starblue

Cô ấy muốn làm điều đó theo một cách hướng đối tượng. Tối thiểu cô ấy cần hiểu làm thế nào để giao tiếp với apis, có lẽ là các đối tượng và các lớp. (Lưu ý rằng tôi chưa làm gì với OpenFOAM vì vậy đó chỉ là một chút dự đoán.)
Eric Pauley

1
Tôi hoàn toàn đồng ý với poster trước của tôi. Nhận thức của bạn về OOP là gì và những gì cô ấy cần để sử dụng thư viện đó có thể khá khác biệt với nhau. Tôi sẽ liên hệ với danh sách gửi thư của thư viện đó và hỏi một số người dùng cao cấp về cách họ tiếp cận vấn đề với lib. Xin đừng cố gắng 'dạy' OOP của cô ấy, điều đó sẽ chỉ dẫn đến sự hiểu lầm, trong khi không giải quyết được vấn đề của cô ấy.
AndreasScheinert

Câu trả lời:


18

Câu trả lời ngắn gọn: không.

Câu trả lời dài: Không có "cách đơn giản" vì OOP không đơn giản. Lập trình thủ tục là tất cả về "biến" và "nếu sau đó goto". Tất cả mọi thứ khác là đường cú pháp, nhưng bốn điều đó là tất cả những gì lập trình thủ tục là về. Một khi bạn nhận được chúng, không có gì có thể ngăn cản bạn.

OOP là một cách để tổ chức các biến và các đoạn mã. Có bao nhiêu mẫu để xác định OOP? 25? 30? Ngay cả những giáo viên học OOP từ các ngôn ngữ và nền tảng khác nhau cũng không đồng ý với định nghĩa riêng của nó, vì vậy ... làm thế nào nó có thể đơn giản?

Tôi không biết làm thế nào bạn đến với điều đó, nhưng vì mẹ bạn có trải nghiệm tương tự với tôi, tôi có thể nói cho bạn biết tôi đã đến đó như thế nào.

Tôi đã lập trình trong C trong một dự án rất lớn. Đó là năm 1988. Nhiều lập trình viên tổ chức các mô-đun và thư viện, với khó khăn trong việc tránh can thiệp vào các công việc khác và giữ sự phân chia nhiệm vụ tốt.

Chúng tôi đã đi đến một "giải pháp" đó là đưa tất cả dữ liệu toàn cầu có liên quan vào các cấu trúc, đặt trong các cấu trúc đó một số con trỏ hàm nơi yêu cầu gọi lại. Chúng tôi khái quát theo cách mà chúng tôi gọi io_mask(sắp xếp các hộp thoại chế độ văn bản) và graphic_managerv.v.

Vào năm 1996, rất dễ dàng phát hiện ra rằng các cấu trúc đó được đặt tên là "các lớp" và các con trỏ hàm đó được thay thế bởi hàm thành viên và các hàm ảo hoặc bằng các liên kết đến các đối tượng khác (được gọi là hành vi) bởi các lập trình viên khác đã làm mới dự án cũ đó.

Tôi bắt đầu hiểu OOP khi tôi bắt đầu cảm thấy sự cần thiết của nó: phân biệt, đa hình và các hành vi được xác định thời gian chạy.

Hôm nay tôi làm việc với OOP, nhưng tôi không nghĩ đó là một học thuyết để phục vụ: chỉ là một "thành ngữ chung" (bộ ...) cho phép chúng tôi nói chuyện với nhau mà không cần phải giải thích và mô tả dài mọi lúc . Trong thực tế, nhiều "quy ước" hơn bất cứ điều gì khác. Rốt cuộc, tất cả OOP làm là -again- "if then goto": nó chỉ thực hiện "nhiều lớp". Do đó trừu tượng và thành ngữ trên thành ngữ.

Mặc kệ họ. Cho đến khi cô ấy không cảm thấy cần họ thậm chí không cố gắng giải thích: cô ấy sẽ cảm thấy chúng giống như một cách phức tạp để làm những việc đơn giản. Và cô ấy đúng ... cho đến khi những gì cô ấy làm là - thực tế - đơn giản.

Sẽ không ai nghĩ đến việc "sắp xếp một cái bàn" nếu chỉ có bốn thứ trên đầu. Nó có ý nghĩa khi những thứ trên đầu bắt đầu can thiệp lẫn nhau. Đó là thời gian để OOP đi vào.

Bạn không cần OOP để làm việc với C ++. Toàn bộ thư viện chuẩn C ++ không được thiết kế theo OOP (mặc dù nó có thể hợp tác với nó) và C ++ không phải là Java.

Theo kinh nghiệm của tôi, các giáo viên C ++ và lập trình viên C ++ tồi tệ nhất là những người đến từ Java, dạy tất cả định kiến ​​của họ về mọi thứ không phải là OOP, làm biến dạng một ngôn ngữ như C ++ không phải (chỉ) cho OOP.

Hãy để tôi đề xuất một cuốn sách hay cho những ai muốn tiếp cận C ++: Tăng tốc C ++ : nó sẽ đưa bạn vào thành ngữ C ++ mà không giả vờ tuân theo một học thuyết được xác định trước.


Cô ấy cần biết c ++ để làm việc với OpenFOAM, vì vậy cô ấy chắc chắn sẽ cần sớm biết các lớp học. Tôi nghĩ rằng cô ấy hiểu những ý tưởng cơ bản đằng sau nó. Tuy nhiên, vì một số lý do, cô ấy dường như bị mắc kẹt trên 'cấu trúc dấu chấm'. (tức là System.out.println (), ngoại trừ trong c ++)
Eric Pauley

@Zencedabone, khá dễ hiểu (và để giải thích) một ngữ nghĩa hoạt động của các lớp, phương thức ảo, v.v (giống như câu trả lời này cho thấy). Đó không phải là một khoa học tên lửa. Chỉ cần tránh xa những "trừu tượng" vô dụng và không liên quan.
SK-logic

1
OOP đơn giản (sắp xếp), C ++ "OOP" thì không. Lấy Smalltalk (đối tượng có các biến thể hiện và một lớp, lớp có các phương thức, bạn gửi tin nhắn đến và đối tượng được phục vụ bởi một phương thức, về cơ bản là nó). OOP định hướng nguyên mẫu thậm chí có thể đưa các lớp ra khỏi phương trình. --- Đó là lý do tại sao tôi khuyên bạn (chỉ có thể) chỉ sử dụng tập hợp con (không riêng tư, không bảo vệ, không const, không thừa kế, tất cả các phương thức ảo, tất cả các hàm hủy ảo, v.v.) để mô hình đơn giản hơn. Thêm những thứ khác sau.
Herby

7

Một người bạn cũ tuyên bố tôi có định nghĩa ngắn nhất mà anh ta biết về lập trình OO và tôi thấy rằng nó hiệu quả với một số người (chứ không phải cho những người khác):

Lập trình hướng đối tượng là dữ liệu với một ý kiến. Bạn không di chuyển cái ghế, bạn yêu cầu cái ghế tự di chuyển. Bạn không sắp xếp danh sách, bạn yêu cầu nó tự sắp xếp (có thể với một gợi ý). Vân vân.

Ý tưởng là khiến người đó suy nghĩ khác về cách mọi thứ được thực hiện trong chương trình của họ.


+1 Điều này cũng đi bằng "Hỏi, đừng nói".
user949300

Bạn có nghĩa là "Nói, đừng hỏi". :)
Ramon Leon

3

Nói cô ấy nghĩ về những đồ vật như đồ vật trong thế giới thực. Ví dụ, toàn bộ thế giới có thể là sự pha trộn giữa lập trình hướng đối tượng (trong C ++) với một số loại lập trình chức năng (có thể được thực hiện bằng ngôn ngữ của thần, Lisp).

Lấy một đối tượng, ví dụ máy cắt cỏ, nó có một thuộc tính nhất định và nó có thể làm một việc nhất định. (đối tượng và lớp)

Sau đó nói với cô ấy về một máy cắt cỏ tốt hơn, đó là một phần mở rộng của máy cắt cỏ mà bạn đã có. Nói với cô ấy tốt hơn nhưng vẫn xây dựng trên cùng một cơ chế (kế thừa).

Sau đó nói với cô ấy về bản thân bạn. Nói với cô ấy đôi khi bạn có thể trở thành một chuyên gia cắt cỏ nhưng thực ra bạn là một lập trình viên và làm việc đó để kiếm sống. Điều này giống như bạn đóng vai trò là hai thực thể khác nhau cùng một lúc. Đây là đa hình.

Khi cô ấy nhận được điều này, hãy nói với cô ấy về cách thực hiện những điều này bằng ngôn ngữ mà cô ấy phải học (C ++).

Sau đó nói với cô ấy, nếu cô ấy phải viết một mô phỏng về thế giới này trong thế giới máy tính, cô ấy sẽ phải học cách làm điều đó.

Khi cô ấy biết cách chuyển đổi suy nghĩ của mình về thế giới thực thành mã chương trình. cô ấy đã học cách lập trình bằng ngôn ngữ lập trình hướng đối tượng.


@Zencedabone không có vấn đề gì, tôi mất 1 năm để học OOP (tôi tự học), nhưng tôi đã sử dụng các ví dụ tương tự :) và đột nhiên cảm thấy giác ngộ. LOL
Aniket Inge

5
Không không không không không! Theo kinh nghiệm của tôi, "nghĩ về các vật thể trong thế giới thực" là một cách khủng khiếp để giải thích OOP cho một người chưa hiểu về nó. Nó dẫn đến những hiểu lầm và ứng dụng sai lầm của OOP, và thường chỉ làm sâu sắc thêm sự nhầm lẫn.
JSB

Các quy tắc cho đa hình giống như Tối ưu hóa. Quy tắc A) Đừng làm điều đó. Quy tắc B) (Chỉ dành cho chuyên gia!): Đừng làm điều đó.
mattnz

1
Đồng ý với JSB ձոգչ. Đó là một cách thực sự phổ biến để giải thích OOP, nhưng theo tôi thì nó thực sự không có ích. Các đối tượng trong lập trình thực sự không có gì giống như các đối tượng trong cuộc sống thực.
Rowan Freeman

Sự khác biệt giữa lập trình thủ tục và lập trình OO về bản chất là trong lập trình thủ tục, bạn nghĩ về một danh sách những việc cần làm theo một số thứ tự và trong OO bạn nghĩ về trạng thái. Nếu mọi người nắm vững trạng thái, họ có thể sử dụng OO một cách hữu ích. Nhiều hơn nữa sau đó cố gắng mô hình hóa thế giới thực.
Pieter B

1

Tôi đã đi từ trình biên dịch chương trình và COBOL sang Ruby.

Điều giúp tôi ban đầu là thực sự bỏ qua khái niệm về các lớp tạo ra các thể hiện.

Chỉ cần bắt đầu với mã. Có một lớp nhưng chỉ có phương pháp cấp lớp. Trong các phương thức, rất nhiều thứ là về các tham số, biến, điều kiện, mảng, chuỗi, Booleans, v.v. Công cụ này nên quen thuộc.

Vì vậy, tại thời điểm này, lớp có thể được coi là chỉ phục vụ mục đích như một nơi để đặt tất cả các phương thức liên quan của bạn vào. Gọi nó là một thùng chứa hoặc một thư viện sẽ quen thuộc hơn với cô ấy.

Rõ ràng mã phải được phân đoạn để có thể quản lý để bạn có một trong những khu vực này. Ví dụ, để quản lý một bộ chương trình tiện ích trên máy tính, bạn có thể có một lớp máy tính nơi bạn có thể đặt tất cả mã cho một máy tính ở một nơi. Nếu bạn chỉ có 1 máy tính trên máy tính thì các phương thức cấp lớp là đủ.

Đó là một sự khởi đầu.

ok bây giờ hãy xem xét thực tế rằng bạn muốn mở nhiều máy tính và thay đổi giao diện của từng cái và vị trí của nó trên màn hình. Vì vậy, bây giờ bạn không thể có một phương thức tính toán như 'screen_location' vì bạn có một vài trong số chúng và mỗi trường hợp có vị trí riêng của nó ... mỗi trường hợp ... ok, vì vậy chúng tôi cần các trường hợp.

Lưu ý: thuật ngữ của tôi là từ ruby ​​chứ không phải c ++ nên bạn có thể cần dịch.


0

Tôi sẽ giải thích nó theo hai bước, hoặc có thể bốn, tùy thuộc vào mức độ bạn muốn phân chia các khái niệm của mình.

Bước 1: Giới thiệu cô ấy với các cấu trúc. Đó là một bước khá nhỏ từ các kiểu dữ liệu Fortran đến các cấu trúc. Bước 1a: đảm bảo cô ấy phân bổ bộ nhớ động và con trỏ dưới tiêu chuẩn.

Bước 2: thêm các thủ tục chỉ liên quan đến các cấu trúc đó. Bước 2a: thêm kế thừa dựa trên việc xây dựng các cấu trúc lớn hơn để "bọc" các cấu trúc nhỏ hơn.

Đối với một lập trình viên Fortran, yếu tố "wow" sẽ là rất nhiều cho trình biên dịch theo dõi. Vâng Đó là những gì trình biên dịch dành cho ...


Tôi nghĩ rằng cô ấy hiểu quá trình đằng sau các đối tượng. Chỉ vì một số lý do mà cô ấy không hiểu được các dấu chấm. ('.') Nó thực sự kỳ lạ. Tôi đoán khi bạn bắt đầu viết mã khi mọi thứ phải được thực hiện thủ công (phân bổ và công cụ), bạn biết cách hoạt động bên trong của các ngôn ngữ hiện đại hoạt động mà không biết cách làm việc với chúng.
Eric Pauley

0

Nếu cô ấy thực hiện luận án của mình một thập kỷ trước, có lẽ cô ấy đã sử dụng Fortan 90 hoặc 95, trong trường hợp đó, điều cần nói về nó liên quan đến các loại dữ liệu dẫn xuất. Nếu cách đây đủ lâu, cô ấy đã sử dụng Fortran 77, sau đó giới thiệu cho cô ấy các kiểu dữ liệu xuất phát trong Fortran 90 và sau đó nói về nó ...

Tôi sẽ không đi vào đa hình và thừa kế, cho đến sau khi cô ấy nắm được đóng gói, vì chúng có thể được xem như là trường hợp đặc biệt và phần mở rộng của đóng gói. Tôi có lẽ sẽ bắt đầu cô ấy bằng một ngôn ngữ cho phép các hàm miễn phí hoặc các lớp tĩnh.


0

Khi cô ấy hiểu các cấu trúc, tôi nghĩ điểm mấu chốt tiếp theo sẽ là nhận ra rằng lập trình hướng đối tượng đóng vai trò là phương tiện để giới hạn tập hợp các phương thức mà một điều có thể được truyền vào, cho tập hợp các phương thức thực sự có thể được áp dụng cho điều đó Điều.

Trong lập trình không hướng đối tượng, nếu một người đang sử dụng các loại dữ liệu riêng biệt cho Cây và LinkedList, thì người ta sẽ phải sử dụng các phương thức khác nhau để thêm một nút cho mỗi loại. Ngôn ngữ không phải hướng đối tượng sẽ thường Squawk nếu một cố gắng để đặt tên cho cả hai phương pháp AddItem, vì bất kỳ tên đưa ra chỉ có thể tham khảo một phương pháp, do đó dẫn một để tạo ra tên phương pháp như AddTreeItem, AddLinkedListItem, RemoveTreeItemvv như vậy một cách tiếp cận tác phẩm, nhưng đó là một chút xấu xí. Về mặt khái niệm, các phương thức AddTreeItemRemoveTreeItemdường như thuộc về nhau, nhưng các tên không sắp xếp theo cách đó. Người ta có thể viết lại những cái tên như TreeAddItem, TreeRemoveItem,LinkedListAddItem, v.v. nhưng điều đó sẽ tạo ra rất nhiều "tiếng ồn dư thừa" khi bắt đầu mỗi lần gọi phương thức. Phần lớn các lệnh gọi phương thức trong một chương trình điển hình sẽ có ba phần thông tin thiết yếu: (1) phần nào của mã nguồn chứa phương thức; (2) phương pháp nào trong phần đang được sử dụng; (3) phần dữ liệu nào đang được thực hiện? Trong nhiều trường hợp, loại dữ liệu được hành động sẽ đủ để xác định phần mã mà phương thức thuộc về, vì vậy phần (1) của phần trên là dự phòng. Dễ dàng xác định trực quan tài liệu khi bắt đầu tuyên bố hơn tài liệu ở nơi khác, do đó, kiểu mã hóa / đặt tên như TreeAddItem(myTree, whatever)cuối cùng đưa phần thông tin ít hữu ích nhất vào vị trí chính.

Ngược lại, sử dụng lập trình hướng đối tượng, người ta sẽ đặt tên cho các phương thức một cách hiệu quả Tree.AddItem, v.v. và một câu lệnh như myTree.AddItem(whatever)sẽ khiến trình biên dịch nói, về cơ bản, "Hmm ... myTreelà kiểu Tree, vì vậy mã này sẽ được gọi Tree.AddItem(). Không cần thiết phải chỉ định Tree.khi gọi AddItemvì trình biên dịch biết loại myTree. Về mặt khái niệm, một câu lệnh myTree.AddItem(whatever)tương đương Tree.AddItem(myTree, whatever)và một số ngôn ngữ hướng đối tượng có thể cho phép cả hai biểu mẫu là tương đương nhau, trên thực tế, hầu hết các ngôn ngữ đều bỏ qua tham số đầu tiên từ đặc tả chức năng và thay vào đó có phương pháp được định nghĩa trong một lớp học như Treengầm lấy một tham số kiểu Tree, và gán cho nó một cái tên như this, selfhoặc Me.

Các ngôn ngữ lập trình hướng đối tượng thường bao gồm nhiều tính năng bổ sung như kế thừa, hàm ảo, v.v ... rất hữu ích trong nhiều ứng dụng, nhưng ngay cả khi không có các tính năng đó, khả năng nhóm các chức năng theo những điều chúng hoạt động là rất hữu ích.


0

Lập trình hướng đối tượng, trong ý nghĩa hướng đối tượng lớp có liên quan ở đây, đó là về việc ghép một biểu diễn dữ liệu với mã thao tác với nó. Nó có ý nghĩa nếu những điều sau đây có ý nghĩa:

  • Khớp nối: xác định một hoạt động cùng với biểu diễn dữ liệu mà nó hoạt động trên

  • Liên kết muộn: chọn kết hợp biểu diễn dữ liệu và hành vi trong thời gian chạy

  • Đóng gói: đảm bảo dữ liệu hợp lệ khi xây dựng và sau đó sẽ không bị vô hiệu

Đó là tất cả. Giống như bất kỳ công nghệ nào , trái tim của nó đơn giản chỉ là sự tiện lợi, từ đó nhiều sự phát triển đã theo sau. Một khi bạn hiểu những điều cơ bản, phần còn lại theo thời gian.


0

Tôi sẽ đề nghị tải xuống BlueJ, chơi với nó trong 20 phút và sau đó cho cô ấy chơi với nó trong 20 phút.

Cách nó trực quan hóa các lớp, giao diện và kế thừa rõ ràng và trực quan đến mức nó thực sự mang đến cho bạn sự hiểu biết tức thì khi bạn thực hiện một cái gì đó - bất cứ điều gì.

Nó thậm chí còn cho bạn thấy sự khác biệt trực tiếp giữa một lớp và một đối tượng

Nó sẽ không cung cấp bất kỳ cái nhìn sâu sắc nào về các mẫu thiết kế OO, nhưng nó sẽ cung cấp một cái nhìn tổng quan tuyệt vời về các khái niệm.


0

Tôi muốn thêm sự đóng góp của mình như một lời nhắc nhở về sự khác biệt giữa mô hình lập trình và ngôn ngữ lập trình thực hiện các mô hình này.

Vì vậy, theo tôi, cách tốt nhất để giải thích hướng đối tượng với C ++ cho người dùng F77, sẽ là tiến hành theo cách thức từng bước:

Trước tiên, hãy giới thiệu cho người dùng khái niệm về hướng đối tượng trong một khung cảnh quen thuộc bằng cách chỉ cho cô cách phát triển các cấu trúc giống như đối tượng trong Fortran 77 - ví dụ, hãy xem các bài báo như B. Patton "Fortran 77 hướng đối tượng (một học viên xem) "SIGPLAN Fortran Forum 12, 2 (1993), trang 23-24 và các tài liệu tham khảo trong đó.

Sau đó, thiết lập một sự tương ứng giữa các cấu trúc đó và các lớp và phương thức C ++.

Cuối cùng, thảo luận về các tính năng bổ sung mà C ++ có thể cung cấp để hỗ trợ lập trình OO.


0

Khi tôi lần đầu tiên chuyển sang ngôn ngữ hướng đối tượng từ khóa đào tạo ban đầu về Pascal, '.' vấn đề là trở ngại lớn nhất đối với tôi quá. Tôi đã mất nhiều năm để vượt qua nó.

Nó thực sự không trực quan khi một biến thuộc về một biến khác, đặc biệt là khi bạn quen nghĩ về chúng như các con trỏ. Sự vấp ngã đối với tôi là:

  • Điều gì có ý nghĩa đối với một cái gì đó về cơ bản là một con trỏ, để có một con trỏ khác trỏ đến nó, nó giải quyết một điều khác với con trỏ cha?

Khoảnh khắc aha đối với tôi là khi tôi nhận ra rằng con trỏ cấp cao nhất về cơ bản chỉ là một không gian tên.

Tôi đề nghị cô ấy viết một loạt mã yêu cầu cô ấy đặt tên cho các chức năng của mình, lý tưởng nhất là không sử dụng ký hiệu dấu chấm để bắt đầu. Sau đó, để cô ấy thử và viết lại bằng cách sử dụng ký hiệu chấm.

Làm bài tập đó sẽ giúp cô ấy vượt qua "Phù thủy này là gì?" rào.


-2

Một cái nhìn sâu sắc quan trọng đã giúp tôi giải thích trước đây là thực tế là bạn có thể có nhiều phiên bản của một lớp. Cố gắng giải thích rằng về mặt "bản vẽ" hoặc "khuôn mẫu" và "bản sao" và xem nếu nó dẫn đến bất cứ nơi nào.


Không thực sự hiểu các downvote. Cách giải thích này đã giúp tôi một vài lần. Không nói đó là viên đạn bạc, nhưng có vẻ như mọi người bị mắc kẹt trong chuyện này.
Alexander Torstling
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.