关于面向对象的一些思考

适才在写python程序,写一个对象的集合容器类,纠结要不要实现迭代器方法来允许for in语句。突然发现,for a in obj和for a in obj.l 给人很大的不同感。我并没有一下子得到明确的思绪(这也不构成问题,仅仅是一个“问题”),想到在哲学群里的争论和一些以前的思考,决定写一篇博客。

  其实写到这里,我已经有些思路了,那就是python不隐藏属性,做不到很好的封装——不过更多地,我也没有刻意区分过“状态”和“属性”(也许“字段”和“属性”对某些人更好些),即一个对象中保存的值在机能上的意义。如果实现迭代方法,那么该类对外就和列表没什么关系。而假如用obj.l的方式,那么这个类仅仅是“列表的容器“(而非自定义对象的容器),列表这个本该多余的概念始终是暴露的,它应该作为隐式的“状态”,而不是供外部访问的“属性”。——在语言层面,python的对象只有属性,但(我觉得)也许某些程序员……会下意识地区分二者,并使用python的“假私有属性”特性——用双下划线开头的名称命名(用作状态的)属性。



  而之前还有一次对于面向对象的思考,和“模板继承”相关。python的format函数可以很方便地作为模板,假如我们需要一个网页模板——即用来生成只有少量几处不同的字符串,我们可以用 待format的 字符串来表示它,然后传入各个值,比如:

template = "<h1>Good {time}, {name}!</h1>"
print(template.format(time="night",name="Amy"))

  而“模板继承”引出了哲学问题。假如:

template2 = "<h1>Good night, {name}!</h1>"

  这个模板显然“应当”从之前的模板“继承”而来。而实现这个“继承”,可以仅仅扩展format函数,添加这样一条规则:

  • 新的format函数对于不匹配的项,不执行替换

  我们可以预计它的行为:

>>> "<h1>Good {time}, {name}!</h1>".format(time="night")
"<h1>Good night, {name}!</h1>"

  这个新的format函数就很有趣了,它拥有普通format的功能!也就是说,假如说普通format“可以将一个模板实例化”,那么对于新的format,“它既可以将一个模板实例化,也可以将一个模板继承出新模板”。这时候我开始质疑自己了,究竟什么是实例化和继承?

  另外这里给出一个新format函数的粗略实现(笑):

def new_format(s,**d):
    class D:
        def __init__(self,d):self.__d = d
        def __getattr__(self,s):return self.__d.get(s,'{'+s+'}')
    s_ = '{0.'.join(s.split('{'))
    return s_.format(D(d))

template = "<h1>Good {time}, {name}!</h1>"  # test
print(new_format(template,time="night",name="Amy"))
print(new_format(template,time="night"))

  我想到了另一个问题:一个无需替换的字符串,固然可以看成一个实例,但何尝不也是一个类呢?这个派生出的类,把基类的初始化参数填满了,不需要其他参数了而已。——接触过偏函数,甚至柯里化的朋友,可以借此比对一下。

  我在面向对象有关的书里,看到过(大致)这样的例子:“水果是一个类,而苹果,梨等等是水果类派生出的实例。”仔细想想便会发现,实际中苹果、梨也是类,而具体的某个苹果,某个梨才“称得上”实例——但是倒不是我批驳这个举例,实例化就是个骗局!(笑)试想在计算机中,我们是如何描述一个“实例”的?一些具体的数据 ,是吧?但是,从哲学上说,任意多的描述都不能指定出一个具体的东西,它依然是一堆描述,而一堆描述正是指定了一个“类”!

  从来都没有实例化,只有继承。——然而学编程不须学哲学,姑且相信实例化并不造成任何实质问题,除了在极少情况下面对“苹果是对象还是类”时会有些困惑……

  不过很多情况下,类已经写死在语言里了。只能说,把我们要泛化的一层看成实例化即可……或者用lua的面向对象系统,或者根本不使用现成的类型系统来表示实际的类(Unity的ECS模型似乎有这种哲学)

  但是从字符串到类,这个比对妥当么?类的继承让功能越来越多,字符串和偏函数却让功能越来越少。类的继承添加了功能。

  不过仔细想想也不矛盾,添加功能也“使自由度变低了”。使用一个类在逻辑上也不能使用子类的功能。

  ………………(我该在自己的语言里实现类来体验一下)



  还有一次思考,是在和别人百般解释不清某个抽象概念,感慨自然语言之其妙。请看如下表述:
  “苹果可以吃

  是不是很奇妙?“苹果”是一个类,但可以吃的东西自然是某个实例(现实中的“实例”还是比较妥的),而此表述没人会误会。但是——

  “梦是假的

  我是由怎样的表述而理解“梦本身是真的”这一情况的?我该如何表达?

  逻辑果然不是人该干的事。

(2018-8-12 于地球)(完)

原文地址:http://blog.51cto.com/13535617/2158462

时间: 2024-09-30 23:53:34

关于面向对象的一些思考的相关文章

面向对象的重新思考

在刚开始学习一门面向对象语言的时候,我们是这样写代码的: 我们会先写一个小狗类,然后new它,最后调用它的方法实现功能. 例如: Dog d=new Dog();//造个小狗 d.shout();//小狗看到stranger会叫 看得懂这段代码,说明你的面向过程语言基础学的不错~~~~~ 好的,这段代码先到这里,我们先来谈谈面向对象的特征: 1,抽象: 首先想想我们在什么时候用到抽象? a.当我在设计一个系统的时候,我需要把一些东西归类,比如,小狗,小猫,这些都会做一个animal类,然后让小狗

day05面向对象

1 面向对象 1.1 万物皆对象 我们是怎么认识世界的? 人类从小就不断的接触到各种各类存在世界上的各种生物,然后通过事物的公共特性,将它们归类,所以以后就不会出现见到猫叫老虎.那么我们在现实生活中,是通过具体的某个事物归纳总结它们的公共特性然后产生类那么类就描述了该种事物的的共别.性,相当于造事物的图纸,我们可以根据这个图纸去做出具体的实体对象. 对象:在现实生活中存在具体的一个事物.; 类:实际就是对某种类型事物的共性属性与行为的抽取. 人类认识世界: 对象----à类. 在java中:  

JavaSE——面向对象与面向过程、类与对象、(属性、方法、构造器)等

一:面向对象与面向过程 二者都是一种思想,面向对象是相对于面向过程而言的. 面向过程: 1.面向过程思想强调的是过程(动作). 2.在面向过程的开发中,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然而由这些功能方法相互调用,完成需求. 3.面向过程的典型代表语言是:C语言. 面向对象: 1.把步骤和方法封装起来,根据不同的功能,进行不同的封装,用的时候,找到对应的类就可以了. 2.将功能封装进对象,强调具备了功能的对象.这就是面向对象的思想.典型的语言是:C++,Java. 3

三、JAVA面向对象

1.面向过程的设计思想和面向对象的设计思想(例如:我要去新疆) ---面向过程:我开车,我挂挡,我踩油门,我过河北...... ---面向对象:我命令车去新疆,车怎么去不关我事(信息封装在车这个类的内部,我不用了解车整个开动的过程) 2.类是用于描述同一类型的对象的一个抽象的概念,类定义了这一类对象所因具有的静态和动态属性. ---类可以看成一类对象的模版,对象可以看成该类的一个具体实例. 3.类(对象)之间的关系 --- 关联关系 --- 继承关系(一般和特殊) --- 聚合关系(整体和部分)

[WuDe]C#程序设计教程 - 第2章 C#面向对象基础

第2章 C#面向对象基础 2.1 类 类是一种数据类型,而对象是具有这种类型的变量 [类的修饰符] class 类名 [:基类名] { //类的成员 }[;] 访问级别的用处在于控制成员在哪些地方可以被访问,这样达到面向对象中"封装"的目的;控制对外访问权限 在类这个级别,不写访问修饰符默认为internal,类只有两个访问修饰符,public 和internal (暂时这样理解),在类里面,方法外定义变量或方法前不加访问修饰符,默认为private Public公共类:不受限制对该类

看Java中==、equals、hashCode的来龙去脉

我有一个哥们去参加了面试,面试官这样问一个Java问题: 你说一下java对象的equals方法调用什么方法呢?我这个哥们想了想,回答说"应该是比较的引用".听了这个答案之后,那个面试官摇头晃脑的说:"不对,你回答的不对,equals方法调用的是hashCode方法".于是乎,我那个技术还不错的哥们就悲壮地栽在这道题目上了. 今天晚上,西安历史上少有的热,那就好好总结一下这个题目的来龙去脉好了,也方便给后面的朋友们提个醒,不要栽在这么简单的问题上.你说这个面试官回答

C#语言-04.OOP基础

a. OOP:面对对象思想 i. 类:是一种功能强大的数据类型,而且是面向对象的基础 1. 语法:访问修饰符 class 类名{ //类的主体 } 2. 成员变量:不以"函数"形式体现 a. 常量:代表与类相关的常量值 b. 变量:类中的变量 c. 事件:由类产生的通知,用于说明发生了什么事件 d. 类型:属于类的局部类型 3. 成员函数:以"函数"形式体现 a. 方法:完成类中各种计算或功能的操作,不能和类同名.不能和类中其他成员同名 b. 属性:定义类的值,并对

初识继承和多态

集成的概念 在C#中,一个类可以继承另一个类,被继承的类通常称为父类或基类.继承其他类的类被称为子类或派生类.派生类的定义可以增加新的数据和功能,派生类的实例也直接可以使用父类的数据或功能,但父类的实例不可以直接使用子类定义的数据或功能 继承是面向对象编程中的一个重要特性.继承关系在类图中表示一个箭头,箭头指向父类如图所示: base关键字和protected修饰符 我们知道this关键字可以表示当前类的实例,通过它可以访问类本身的成员,在C#中还有一个base关键字表示父类,它可以用于访问父类

黑马程序员java-交通灯管理系统《十》

                   --Java培训.Android培训.iOS培训..Net培训.期待与您交流! -- 1,交通灯管理系统原理与分析 首先明白它的工作原理,由于刚刚学车,大概明白交通灯是如何运作的,一般来说车右转是默认不用看灯的,可以直接右转的, 但有时候当交通有箭头显示的时候又不一样了,所以我们不考虑这种情况.那么默认右转灯是一直绿的.根据东南西北四个方向 的车都有各自的三种路线,按道理,东南西北四个方向都有各自的三个方向的交通灯.从车方面考虑就有12(3x4)种路线,而