【问题标题】:How to teach Object Oriented Programming - Any idea where to start?如何教授面向对象编程 - 知道从哪里开始吗?
【发布时间】:2010-01-02 09:53:34
【问题描述】:

我在高中、计算机培训机构等教授 C++ 大约 2 年。在教授有关变量、数组、结构、函数的基础知识后,我总是从传统示例开始面向对象示例部分,例如:

class Person {
public:

 Person();
 ~Person();
 char* getFirstName(); //we can use std::string instead of char* in optimization part
 char* getLastName();
 char* getFullName();
 int getAge();
 bool getGender();
 void printFullProfile();

 void setFirstName(char*);
 void setLastName(char*);
 void setAge(unsigned int); 
 void setGender(bool);
 void setGender(char);//f for female, m for male.

private:
 char* first_name; //or std::string but i prefer to use pointers in the beginning.
 char* last_name;
 unsigned int age;
 bool gender; //ladies 1(st) , male 0
}

然后完成这个 Person 类并教授新知识,例如为什么 getter 和 setter 方法是邪恶,并通过创建其他类(如 Student、员工、版主等),必要的 OOP 技能和概念。

[编辑]: 并使这些类对解决编程问题有用。 (比如计算每个 Employee 对象的薪水,学生平均成绩等等)

另一个基本示例是 Vehicle 类、Shape 类等。

我想知道您对如何(只需)开设 OOP 课堂的想法。

期待伟大的想法。

【问题讨论】:

  • 对您的示例的一些建议:1. 我几乎从不鼓励在使用 C++ 时使用 char* -- 而是使用 std::string, 2. 不需要每个设置器函数类的成员(这对教授封装的含义很重要)
  • 恕我直言,C++ 是教授 OOP 原理的糟糕选择,因为它的许多基本功能都不是真正的 OO - 例如模板。话虽如此,我不认为完美的面向对象教学语言存在:-(
  • 小提示。不要使用缩写的字段和函数名称。通过键入“fname”而不是“firstName”来完成什么? “firstName”一目了然,不会让新手想知道为什么到处都是有趣的缩写。
  • 我真的不喜欢用布尔值来表示性别。即使男人有“额外的一点”。

标签: c++ oop


【解决方案1】:

我会从无代码开始,使用 CRC 卡。让班级发挥卡片角色,并进行真正的OO设计会议。在那里你可以介绍单一责任原则,谈论has-a vs is-a和继承、封装。我遇到太多的程序员,他们对 OO 一无所知,还在用 c++、c#、java 或 delphi 编程。

[编辑] 稍后您可能想将基于类与 javascript(或 self)和基于原型的 OO 进行比较,以讨论不同的分类方式。

【讨论】:

  • +1 好建议。但我不是从代码开始我的课堂。我编辑了我的问题。谢谢
  • 我最近尝试了你的解决方案,这对学生来说很有趣,我意识到他们在 OOP 的概念上比实现更困难。因此,CRC 卡具有魅力:)
  • 正如@justsomebody 在他的回答中提到的那样,我不会使用 C++ 教授 OOP,Java 是我选择的语言。
【解决方案2】:

正如其他人所建议的,使用现实世界的例子来解释事物;比如用于继承的 Vehicle 类和 Truck 类。但这是重要的部分。一旦他们了解了现实世界的示例,他们接下来需要查看与程序相关的示例,然后才能真正理解为什么它对编程很重要。

我见过很多糟糕的 C++ 代码,而且不仅仅是来自不懂这些概念的人。我见过很多程序员,他们确切地知道对象是什么,并且可以完美地解释多态性和所有这些技术 OOP 术语。但如果他们不知道何时使用它,他们将永远无法充分利用它。我知道,因为我自己就是这样。我在高中时读过一本关于 OOP 的书,它解释了所有的概念,但我在实际使用它们之前已经过了好几年,因为我没有看到它们何时真正有益于我的代码。尝试在没有 OOP 的情况下进行编程作业将更具挑战性。学生自然会走更简单的路线并开始理解。实践是最好的学习方式。

你可能有一个链表类,并要求他们通过编写自己的 push/pop、enqueue/dequeue 方法来继承它以创建堆栈或队列。或者创建一个二叉树类,并要求他们通过覆盖 insert 方法使其成为二叉搜索树。让他们使用动态内存,这样他们就可以看到为什么[复制]构造函数/析构函数很重要。让他们编写一个计时器类,将时间存储为秒,但使用 getter/setter 自动转换为/从分钟或小时。

我不知道您的学生是否从一开始就使用 char 数组或 std::strings。让他们同时使用。当他们了解 char 数组有多难时,他们会更加欣赏字符串类,并理解类的重点是抽象,而不仅仅是代码组织。如果您的学生确实询问过代码组织并且不确定特定数据或方法应该去哪里,请记住这句话:

“事实上,我会声称一个糟糕的程序员之间的区别 一个好的是他是否考虑他的代码或他的数据结构 更重要。糟糕的程序员担心代码。优秀的程序员 担心数据结构及其关系。” - Linus Torvalds

【讨论】:

    【解决方案3】:

    首先要避免使用 getter 和 setter 的类。 OOP 的主要承诺之一是“数据和程序结合在一起”。它旨在解决程序程序中长期存在的问题:数据结构在一个地方的更改会随着数据流动而在程序中产生涟漪。 OOP 通过确保数据保持原状来解决这个问题。 getter 和 setter 只是一种规避 OOP 的机制(a->setX(y->getX()) 中的数据传输),你最终会得到一堆样板文件。

    另外,不要使用 C++ 教授 OOP。使用专为 OOP 设计的语言。具有真正封装的东西(对私有成员的更改不需要重新编译客户端代码)并统一处理所有类型(例如字符串文字是第一类对象)。

    【讨论】:

    • 我在我的问题中忘记了一些东西(已编辑!)。我同意“不要使用 C++ 教授 OOP”部分,但我可以在 C++ 课程中教授 Java 或 Python 吗?
    • 你可能会做 Smalltalk
    • @Stephan Eggermont ... Smalltalk 是纯 OOP 语言,但我支付了 C++ 教学费用:D
    • @Michel:在这种情况下,不要教 OOP。 C++ 是一种糟糕的语言,可以教授任何范式,也许除了程序性。教他们如何将他们学到的东西翻译成其他更简洁的语言。
    • +1 用于避免 getter 和 setter。如果您发现自己这样做了,只需使用结构并放弃在 OOP 意义上拥有对象的假装。
    【解决方案4】:

    我不会使用 C++ 来教授 OOP,因为 C++ 并不是一门优雅的语言,而且 OOP 在 C++ 中有些奇怪。我更喜欢 Java 或 Scala 或者 Python,这是一种很好的教学语言。我的第一选择是 Scala,因为它有很强的概念。例如,没有静态成员会破坏 oop。不要忘记,如果编程有趣(C++ 没那么有趣),教学会更有效。

    我会介绍:

    • OOP 的目标是什么?
    • 具有继承和接口的多态性
    • 对象的责任
    • 封装
    • 对象之间的消息

    【讨论】:

    • @deamon 我同意你的看法。 C++ 不适合开始教授 OOP,但在 C++ 课上我别无选择。我可以在 C++ 课上教 Java 或 Python 吗?我不这么认为......
    【解决方案5】:

    如何展示这些与编程有什么关系?有人告诉你“你可以使用类来模拟物理对象,比如一个人”,这有什么好处?

    这与他们试图学习的内容有什么关系?也就是编程?

    这种“教授”OOP 的方式完全是无稽之谈,对于不已经熟悉 OOP 概念的任何人来说都是完全没用的。

    如果您想教授 OOP,请向他们展示一些在编程中有用的东西。诸如类之类的 OOP 概念如何帮助解决实际的编程问题?他们是否提供了比他们必须使用的解决方案更清洁的解决方案?

    很容易接受“我们可能有一个 Person 类”的抽象事实。也很容易接受“我们可以从这个 Person 类派生出一个更专业的人的类,比如看门人、儿童或妇女”。缺少的是关于这在编程中如何有用的任何线索。继承在解决编程问题中有何用处?多态性如何有用?为什么我们关心数据隐藏?

    就此而言,您的具体示例给我们带来了什么?它只是一个 getter 和 setter 的列表。几乎没有数据隐藏。没有抽象。它只是围绕我们一直以来可以做的事情的额外代码。如果你写不出的课,你有资格教书吗?

    看在老天的份上,请使用 std::string 而不是 char*。是的,这意味着您必须告诉您的学生“std::string 是一个字符串”,但至少您不必面对 char 指针管理的所有混乱和噪音。保持你的代码干净,没有多余的噪音。

    【讨论】:

    • 谢谢@jalf。我在我的问题中忘记了一些东西,只是对其进行了编辑。 “那么,你的具体例子给我们带来了什么?”你提出的例子是什么?这就是我想知道的
    • 一年多后我再次检查了我的问题。但没有你的回应。您建议的“现实世界”示例是什么?一个我们可以称之为“好课”的课?让我们知道。
    【解决方案6】:

    随着当今编程世界中接口的重要性日益增加,我将专注于您的类的作用(行为)而不是它的字段和属性。这有助于强化“Is-A”思维的概念(又名Liskov Sustitution Principle)。

    【讨论】:

    • 对象由状态和行为组成。
    • 是的,当然可以。但是,我见过太多看起来像美化实体关系图的类设计。许多类最终有很多字段,几乎没有方法。在这一点上,将它们应用到 MVC 平台等是一个相当大的挑战。
    【解决方案7】:

    众所周知,面向对象的概念与人类非常接近,所以当我从 oo 概念开始时,我总是给出实时示例,这会产生很大的不同.. 前任... -- 多态性:多态性的实时例子是“我”我自己看到只有一个人是我,但我有不同的角色,比如当我在家的时候 1. 我是我父母的儿子。 2. 当我在学校的时候,我是老师。 3.当我在地面上时,我就是一名球员............只看到一个人,即我,但我有不同的角色......即多态性

    -- 抽象:我是一名老师,你们(学生)对我的教学感兴趣,而不是我为收集这些数据所做的工作以及我昨晚所做的工作。即抽象避免给用户不想要的东西。

    【讨论】:

      【解决方案8】:

      当我教授面向对象编程时,我尽量不从代码开始,而是从概念、想法和原因开始。这里是 a horrible Google translation 的原始 Swedish web page,我在那里写了我用来给出的 OO 介绍。

      【讨论】:

        【解决方案9】:

        如果时间允许并且学生渴望并且能够学习。您可以教他们编写简单的 GUI 程序,而构建 GUI 也是 OOP 擅长的地方。

        Qt 是用 C++ 精心设计的,非常适合这项任务。学生在看到现实世界的例子之前无法理解继承、虚函数。

        【讨论】:

        • @Michel 是的。在教授了一些基本概念之后,您可以使用简单的 GUI 程序来说明 OOP 的风格和功能。我建议使用Qt,我们大学的C++ OOP 课程中有1/4 是使用Qt。学生喜欢这部分:)
        • 我同意“在教授一些基本概念之后”部分。我也同意 Qt 部分。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-03
        相关资源
        最近更新 更多