你如何向新程序员解释OO?

时间:2008-12-10 11:44:01

标签: oop language-agnostic

我的亲戚正在学习编程,很难理解课程。他很难理解,例如你需要实例化它,方法不能在其他方法中访问变量,如果你在一个类的实例中更改变量,它对其他实例不会改变。

我试图使用像类定义这样的类比就像一个房子的蓝图。实例是由该蓝图制成的房屋。

你如何解释一般的课程和OO?

17 个答案:

答案 0 :(得分:20)

我通过我的妻子(特许会计师)获得的最佳方式如下:

在“常规”编程中,您拥有数据(被操纵的东西)和代码(操纵的东西),它们是分开的。有时你会混淆,因为某段代码试图操纵错误的东西。

在我妻子的情况下,我说收到发票(没有实物转手),并且不小心更新了银行存款,她立即认为这是潜在的欺诈行为(她曾经做过法务会计,一切都是潜在的欺诈行为。 ,包括我的大部分股票交易: - )。

你可以很容易地说,用一把巨大的拖把洗地板的一段代码决定用你的牙刷来做。

通过OO编程,操纵器和操纵器不可避免地缠绕在一起。您不要将地板清洗过程应用到地板上,而是指示地板自行清洗。它知道如何执行此操作,因为代码是对象的一部分,而不是外部的代码。

在上面的会计案例中,我认为我们最终将会计科目表作为对象,并且我们告诉它将发票应用于自身。由于它理解了这个过程,因此它知道允许更新哪些帐户(债权人责任帐户和费用帐户,如果我没记错的话)。

无论如何,这是无关紧要的,我现在只是在蜿蜒。我所说的是用目标受众理解的术语来表达它。我想这是大多数教学的秘诀。

答案 1 :(得分:20)

认真使用动物,效果很好。这就是多年前为我设计这个概念的原因。刚刚找到了这个C#代码。好像很好

    // Assembly: Common Classes
    // Namespace: CommonClasses

    public interface IAnimal
    {
        string Name
        { 
             get; 
        }
        string Talk();
    }

    // Assembly: Animals
    // Namespace: Animals

    public class AnimalBase
    {
        private string _name;
        AnimalBase(string name)
        {
           _name = name;
        }
        public string Name
        {
           get
           {
              return _name;
           }
        }
    }

    // Assembly: Animals
    // Namespace: Animals

    public class Cat : AnimalBase, IAnimal
    {
        public Cat(String name) :
            base(name)
        {
        }

        public string Talk() {
            return "Meowww!";
        }
    }

    // Assembly: Animals
    // Namespace: Animals

    public class Dog : AnimalBase, IAnimal
    {
        public Dog(string name) : 
            base(name)
        {
        }

        public string Talk() {
            return "Arf! Arf!";
        }
    }

    // Assembly: Program
    // Namespace: Program
    // References and Uses Assemblies: Common Classes, Animals

    public class TestAnimals
    {
        // prints the following:
        //
        // Missy: Meowww!
        // Mr. Bojangles: Meowww!
        // Lassie: Arf! Arf!
        //
        public static void Main(String[] args)
        {
            List<IAnimal> animals = new List<IAnimal>();
            animals.Add(new Cat("Missy"));
            animals.Add(new Cat("Mr. Bojangles"));
            animals.Add(new Dog("Lassie"));

            foreach(IAnimal animal in animals)
            {
                 Console.WriteLine(animal.Name + ": " + animal.Talk());
            }    
        }
    }

一旦他被钉上了,你就挑战他定义Bird(飞),然后企鹅(飞!)

答案 2 :(得分:8)

像所有老屁一样,我想用自己生活中的故事回答这个问题。

我开始在VIC-20上编程基础。不知道其他什么,我虽然这是所有计算机的编程方式。我认为跟踪哪些变量名称以及哪些变量仍然是免费的(范围问题)有点困难。我还认为使用gosub-return以及设置和读取这些将使用的变量(缺少方法)很难将我的程序划分为可重复的块。

然后我通过MS-DOS进入了Turbo C.现在我可以创建自己的方法和功能!我不再坚持基本的旧有限命令集。我觉得我正在为我编写的每个程序创建一种新语言。 C给了我更多表现力。

C ++是我听过的第一个面向对象的语言。对我而言,最重要的时刻是我明白我可以创建自己的数据类型,甚至超载运算符。再一次,我觉得我可以创建自己的语言,包含新功能和数据类型,并配有运算符。

这就是我如何向新的程序员出售OO。说明它具有表达能力,因为它们可以定义自己的数据类型。我一直认为封装是比继承更好的卖点。

答案 3 :(得分:4)

我是第二个'动物'方法!

关于JavaRanch的这篇小文章,“我的狗如何学习多态性”对我帮助很大(它几乎与语言无关):

http://www.javaranch.com/campfire/StoryPoly.jsp

答案 4 :(得分:3)

在向动物解释OO时,不要忘记用Stinger missiles-armed kangaroos来说明“is-a”关系; - )

  

正如预测的那样,袋鼠分散了,美国人赞赏地点了点头。 。 。当袋鼠从山后重新出现并在倒霉的直升机上发射了一连串的毒刺导弹时,他们做了一次双重拍摄。 (显然程序员已经忘记了删除步兵编码的“那部分”)。

     

上课?使用某些属性定义对象,并且根据旧属性定义的任何新对象都会继承所有属性。尴尬的程序员在重用面向对象的代码时学会了小心,并且Yanks最为尊重澳大利亚野生动物。

答案 5 :(得分:3)

我假设目标知道如何使用图形用户界面。我发现最好的方法是用他们真正用过的东西来描述OOP。说

窗口是一个类。它有像

这样的方法
  • 显示一个窗口
  • 启用窗口
  • 设置窗口标题

一个窗口有属性。那是与它相关的数据。它是封装进入类,以及对其进行操作的函数

  • 窗口有尺寸。宽度和高度。
  • 窗口可能有父窗口,可能还有子窗口。
  • 一个窗口有一个标题

对象

有很多窗户。每个特定窗口都是类 Window 的对象。包含10个窗口的父窗口生成11个Window对象。

Deriveration

按钮 窗口。它的维度有一个父窗口,并有一个标题,一个按钮的标签。它是窗口的特殊类型。当你要求一个窗口对象时,有人可以给你一个按钮。按钮可以添加特定于按钮的功能和数据:

  • 按钮有状态。它可以处于按下状态和未按下状态。
  • 按钮可以是窗口中的默认按钮。

答案 6 :(得分:2)

阅读Java tutorials了解一些好主意和现实世界的例子。

答案 7 :(得分:1)

如果他们已经足够大,可以填写税表,请向他们展示1040EZ并解释一个类的实例就像一个填写的表格:每个空白是对象的成员变量,并且表单还包括有关如何处理成员变量的说明,这些指令是对象的成员函数。类本身就像是表单的主副本,您可以从中打印出无数的空白表单来填写。

我试图向新程序员传达OO的概念 AVOID 的一件事是仅使用对象(在OO意义上)代表真实世界的物理对象的例子。这实际上会让学生在遇到用于表示非物理对象的对象(例如颜色方案或“设计模式”中的大多数行为模式)或仅用作对象的对象时感到困惑更多将相关函数和相关数据存储在同一个地方的有用方法(以Java的java.lang.Math为例。)

答案 8 :(得分:1)

“使用模具构建每个模具”或“每个模型是使用模板构建的”,“每个对象是使用类构建的”,如何?

请注意,它适用于面向类的OOP(这是您想要的),但不适用于面向原型的OOP。

至于向程序员解释OOP,我会添加说明的例子:

将状态与行为分开

大多数情况下,实例描述状态,而类描述行为。

实例将其行为委托给其类,然后该类可以将其行为委托给其超类(或mixins或traits)

多态性

如果A类继承自B类,则可以在任何可以使用B类实例的地方使用A的实例。

消息&amp;方法

消息(或通用函数或虚函数)就像一个问题。大多数时候,几个班级都可以回答这个问题。

相应的方法是问题的可能答案,它位于一个类中。

当向实例发送消息时,实例会在其类中查找相应的方法。如果找到,则调用它(实例绑定到'self'或'this'。否则,它会在其mixins,traits或superclasses中查找相应的方法,并调用它。

答案 9 :(得分:1)

信不信由你,体育

我通过谈论如下的方式在教学和辅导方面取得了成功。根据各种位置(中心,四分卫,跑卫等)如何相互作用来完成特定目标,描述了足球队的比赛。在一个版本中,职位对应于班级,而特定人员(Tony Romo,Johnny Unitas等)是班级的实例 - 表现出与职位相同的行为的个人。

这个比喻的第二个版本是解释位置可能是接口(在Java意义上)而不是类。接口实际上代表实现接口方法的任何对象所实现的角色。对于一个对象(通过它的类,在Java中)实现多个接口是完全合理的,就像一个有才能的人可以在一个运动团队中扮演多个位置一样。

最后,游戏就像一个模式,因为它描述了一组角色如何相互作用以实现某个特定的目标。

答案 10 :(得分:1)

一个物体是一个黑盒子,你无法透视。公共方法是它们上的按钮。受保护的方法是隐藏在底部的按钮,私有方法是内部的dip开关。

让我们看一个洗衣机作为对象。我们不知道它是如何工作的。我们不关心它是否由天然气,柴油,电力或钚提供动力。然而,机械和内部结构将根据能源而变化很大,例如某些人需要内燃机。我们不在乎,只要我们按下“洗涤”按钮,它就会洗掉我们的衣服。

让我们把洗衣机变成面向对象的。将所有按钮排列在顶部,露出所有按钮。客户现在可以通过调整一些拨码开关对发动机进行涡轮增压。使机箱透明。现在,您可以看到您的节能洗衣机实际上是混合动力的。里面有一些猴子。你将它们释放到野外,机器就像一个耗油的人一样吃掉你的公用事业账单。

答案 11 :(得分:0)

我解释说,程序程序是围绕系统的“动词”构建的,是系统要做的事情,而面向对象的程序设计是关于“名词”,系统中的事物,以及它们是什么能够,并且对于许多人来说,这允许从问题域到软件的更直接的映射。

例如,我使用汽车 - “本田雅阁”是一个类,而坐在停车场的车辆是一个物体,一个本田雅阁的实例。本田雅阁是一款轿车,它是一种汽车,是一种汽车,是一种机动车,这是一种交通方式等。在我有一辆实体车与之合作之前我无法做任何事情 - 本田雅阁的概念存在并不能帮助我。

它还有助于讨论界面和多态性 - 加油踏板意味着加速,无论汽车在幕后做什么来实现这一点。我用户无法访问汽车的“私人”部分 - 我不能直接应用单独的制动器。

答案 12 :(得分:0)

面向对象编程是一种提高程序员与计算机通信的抽象级别的技术:从打开和关闭各个位的级别,从纸卡的打孔级别,从基本指令代码的非常复杂的序列级别,从数据块和可重用代码块(结构和过程)的可重用模板的不太复杂的定义级别到将程序员的思想中的概念转录为代码的级别,所以对于程序员来说,计算机内部发生的事情变得类似于物理对象,无形资产和因果世界中计算机外部发生的事情。

答案 13 :(得分:0)

我面对面向对象编程的最好的书是Betrand's "Object-Oriented Software Construction" - 如果你真的想要掌握基础知识,那就没办法了。

答案 14 :(得分:0)

由于问题是要向新的程序员而不是母亲或妻子解释,我会直截了当地说明问题。 OO主要涉及三个主要概念:

  1. 继承:狗是动物,亲子,是 - 关系测试等。
  2. 封装:公共 - 私有(受保护),信息隐藏,内部底层细节对于类的用户并不重要,保护用户免受未来实施中的更改。
  3. 多态性:运行时绑定,后期绑定,被调用的方法取决于对象的类型,而不是对象的引用或指针。
  4. 此外,根据新程序员使用程序语言的程度,我需要帮助他/她忘记函数或程序不再是中心。

答案 15 :(得分:0)

游戏很好。 有游戏对象,从这些墙壁,敌人和玩家继承。 游戏对象应该是可渲染的,具有碰撞逻辑等。当玩家受键盘控制时,敌人具有动态逻辑。

一些UI元素也很好,有些按钮,输入框等都是从一些基础对象继承而来的,它们具有管理鼠标事件等的代码。

我不喜欢动物的例子,因为我从未见过曾经以这种方式使用动物的“真实”程序。它只会让人们在整个地方使用继承,你最终会得到从行继承的矩形继承的多维数据集(为什么这么多书仍然坚持使用它作为例子?)。

答案 16 :(得分:0)

OOP是一个更高级别的抽象,程序员无法真正掌握它,除非他非常了解正常(读取:程序)编程方式,并且他必须能够编写一些程序有用的东西。

对我而言,由我的一位大学教授进行了一系列的讲座,在那里他讨论了编程的许多理论方面,他试图说服我们编程是关于操纵数据,而这个数据代表了“状态程序,以及我现在忘记的其他一些抽象的东西!但问题是,如果没有一些理论上的抽象讨论,那么很难理解OOP,而这种讨论对于没有经验编写实际代码的人来说没有任何意义。

在理论讨论之后,你举一个中等复杂程序的例子,用程序风格编写,然后逐步将其逐步转换为面向对象的风格。在具体的例子之后,你应该回到理论上的讨论,只是总结一下要点,直接将理论结构与具体的例子联系起来,例如,你可以谈谈一个雇员的姓名,年龄和工资如何代表他的国家。