class Person {
    /**
     * 姓名
     */
    public $name;
    /**
     * 年龄
     */
    public $age;
    /**
     * 性别
     */
    public $sex;

    /**
     * 说话
     */
    public function say() {
    
    }

    /**
     * 制造工具
     */
    public function makeTool() {
    
    }

    /**
     * 思考
     */
    public function ponder() {
    
    }
}

抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征。


    这句话是我从百度百科当中复制过来的,也许,有许多程序员都是以上述定义来描述抽象,包括我,那么我们就来分析一下这个定义。

    准确的说,这是一个哲学中抽象的定义,它强调了所提取的特征必须是共同的、本质性的,我们以此为依据来看看上面的 Person,你有没有发现一些不妙的地方?我们在 Person 中定义的属性与方法中,有一部分并非是本质性的:

    人没有姓名就不能称之为人了吗?

    人不能说话就不能称之为人了吗?

    年龄、性别是人的本质吗?

    我记得以前某门科目的教科书上关于人的描述主要有两点:能够制造工具以及能够思考;参考这个,也许我们的 Person 中只会剩下 makeTool 和 ponder 这两个方法了。

 

    哲学已经存在了许多年,而软件开发仅仅是近年才兴起的事物,我相信软件开发中的抽象一定是来源于哲学的,我们甚至沿用了哲学当中关于抽象的定义(也许有专门的定义,请知道的朋友告诉我)。但是软件开发当中的抽象却做出了改变,这种改变是什么促使的呢?

 

    我们先来看看如何使用 Person:

 

    $xiaoming = new Person();
    $xiaoming->name = "xiaoming";
    $xiaoming->age = 10;
    $xiaoming->sex = "男";

 

    进行上面工作之后,我们就可以使用这个对象了,很方便不是吗?是的,正是为了方便,为了更好的复用才促使我们做出了这种变通,假如我们不作变通情况会如何呢?

 

    class Person {
        public function makeTool(){}
        public function ponder(){}
    }

    class XiaoMingPerson extends Person {
        public $name = "xiaoming";
        public $age = 10;
        public $sex = "男";
        public function say(){}
    }

    $xiaoming = new XiaoMingPerson();
 

 

    情况是不是变的糟糕了?每当我们需要创建一个人的实例的时候,我们都不得不为他定义一个 xxxPerson,多么蛋疼的事情。也许我们有其他的方法在一定程度上简化上面的代码,比如我们为 Person 创建两个子集,一个是 “可说话的人”,一个是 “不能说话的人”,这样 say 方法在 “可说话的人” 这个子集中就算的上是本质性的了,然后 XiaoMingPerson 从 “可说话的人” 派生,但是终究很麻烦不是吗?

 

    软件开发当中的抽象更多的强调了共同特征,而在很大程度上忽略了本质性特征。这是由我们所做的事情决定的,我们会衡量我们将要创建的实例或子集当中都有哪些共同特征,然后我们将这些共同特征一股脑的放到抽象里,最大化的复用,来实现更简单的创建子集或实例。

 

 

    好吧,我又辞不达意了,我本来想多写点东西,但是仔细想想,我还是另开一篇吧,这篇的标题我也改一下,就这样了。

 

posted on 2012-05-16 23:02  牛哄哄  阅读(248)  评论(0编辑  收藏  举报