面向对象

Posted jiumao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象相关的知识,希望对你有一定的参考价值。

 

面向对象

Java是支持面向对象编程的语言,java设计思想参考java之父James Gosling的一次谈话 http://www.artima.com/intv/gosling1P.html 。设计简单,易于理解,多用于开发Internet

应用软件。90年代的许多软件开发思想得利于Smalltalk语言。

本文试图从多继承、封装、多态、闭包的实现来说明几种语言面向对象编程的特点。包括:不同访问权限,如私有、公有;类属性(静态)与对象属性(只属于每个对象);接口、抽象方法;常量、变量。如果你是某种语言的专家,请指正。

动态语言?

作用域

类与对象

javascript

var声明为当前作用域,否则为全局。

静态类型通过语言内置原型prototype字段,隐式支持。包括构造器constructor

动作方法只支持封装functionjson可作为数据类型封装。

ECMA6支持class

规范:接口的实现通过巧妙的编程设计来实现。JS的设计非常简单,可读性和功能很强大

Python

__ 下划线声明为私有字段,否则为共享字段

方法可以定做在类中也可以在类外(文件中)。类外方法可以作为静态方法,另外类方法、接口、抽象方法通过注释实现。

class关键字支持。def关键字定义方法。有构造方法和析构方法。以及类似静态构造方法new方法,只执行一次,在所有方法之前执行。

通过人工手段实现规范,非原始支持这些规范。

php

已经启用var关键字,通过其它关键字声明作用域,语法类似Java。可读性很强。

变量作用域关键字支持全面

class 等支持良好。

编译语言?

  

Go

C语言为原型。通过首字母大写为作用域。通过包来区分一组功能,没有类的概念。main方法为程序入口,不同操作系统编译为不同的可执行程序。

方法、接口、数据结构()等是同一个级别的。在Java中方法属于类,是隶属关系不平等。

新的编程思路的设计语言。非常有趣。

Scala

JVM平台语言,高阶函数支持。语法略显臃肿,或者说这样让面向对象设计的思维负担减轻(这个懒是不能偷)。支持太多,或者说不是好事。

class有一个伴生对象用Object关键字声明(单例设计)。可直接声明函数,函数不同于方法,方法定义类或者伴生对象中。伴生对象即静态支持。

Java

通过关键字声明作用域,static为所有对象共享。可读性非常好。规范性强,需要较多的设计技巧,良好支持企业级多团队开发。

C语言系列语言。

 

Javascript

关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。————百度百科。

本文没有使用ECMAScript 6的新特性。如classextends

对于JS面向对象的详细了解,请点击这里

在文件中声明作用空间,类似java中的package。目的是区分

类模板,复用此类模板

在任意一个*.html文件中测试,直接用浏览器打开即可。

注释掉上面的测试数据,上面的属性为对象私有。下面介绍类属属性。对象共享类似静态属性、静态方法在javascript中的设计。JS中属性可以动态按需增加或删除。var声明变量为当前作用域类似private,但不是访问限制。不加代表全局作用域。

 

这里的原型只能通过类(即方法名).prototype来使用。

 

继承

Person中加入原型属性,保持父类原型非空有意义。

  • 子类原型保存父类模板以及原型,但用父类构造方法且保存了值。这适用某些情况。

  • 模板继承,解决了上面继承值问题。但不继承原型。

Teacher类继承Person

ECMAScript规范给所有函数都定义了Call()apply()两个方法,callapply的第一个参数都是需要调用的函数对象,在函数体内这个参数就是this的值,剩余的参数是需要传递给函数的值,callapply的不同就是call传的值可以是任意的,而apply传的剩余值必须为数组。

  • 把继承抽象成工具方法,继承原型而不影响父类。但仍需要子类绑定模板。

 

 

prototype会形成原型链,对象的属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。上面:子类sub的原型是F的对象,同时F也有自己的原型,F的原型是父类sup的原型(对象)以此类推到ObjectObject的原型对象为null

这里需要注意的是所有的实例对象共享constructor,而constructorprototype的属性,所以在修改原型对象的时候一定要还原构造器。

这里相等于JM.Sup.callextend方法中的F空函数是必要的,否则会在call中递归调用发生异常。

测试

如果要实现多继承,可以定义supClass数组或维护对应继承数量个变量。

接口实现

这里模拟写一个数组实现的集合

 

闭包实现

这是例子假定不同浏览器有不同的显示策略。根据不同的浏览器标示,匹配不同的配置文件。返回结果是个单例。

 

单例方法,模拟浏览器标示。

不同配置策略

单例实现

测试

 

PHP

PHP 语法

定义一个类模板,演示封装。其中有类常量,全局常量,超全局常量。静态属性、静态方法。

新建个文件Package.php,用于封装的测试

$this 关键字指代对象,self指本类,parent指父类。类属访问用::,否则用->

var关键字在PHP后续的版本不推荐使用了。

构造方法

析构方法

这个简单的类模板,演示了作用域publicprotectedprivate 修饰的成员或者方法。类常量用关键字const,一般大写,它的涵义表明了作用域。全局常量用define(name,value)Php中常量跟变量有区别。下面的子类演示了静态变量、静态方法的定义。

测试方法

静态变量属于类,可以改变。Php中常量不允许修改。

在另外一个php文件中写测试,require_once 引入要测试文件。

析构方法执行

接口与抽象类

PHP中接口与抽象类与java很相似,区别:不同的东西,抽象类不能实现接口。

接口

实现类码农先生

抽象类

抽象类的实现类,final 关键字与java相似,但只作用类

测试,hi(方法名,参数列表)hi方法并没有定义。

 

Python

*.py文件,第一行说明文档字符集。这是一个单例例子。类属私有变量、公有变量、方法,对象绑定变量、方法。构造、析构方法。

__field表示私有变量,否则为公有。

上面的getName传入对象,类似java getter方法。__new__在构造方法前执行,返回实例对象。这些在类中直接定义的方法都是对象方法,不能用类调用。

内部类的__call__使类变成可调用的函数。函数可以直接在外部定义,下面会解释。

类方法、静态方法要加对应注解,区别在于第一个参数是不是类的对象实例。这里say()方法应该是表达,赋值显得有些语言不是很准确,只是希望多表达一些功能。

测试及结果

这里的例子为了说明python的封装。

#优势 动态添加属性 object.field=value 删除del

 

 

接下来是继承、接口规范的测试。

子类没有重写构造方法时会继承哪个?默认继承第一个,如果我们没有注意继承顺序或者分别需要不同方法,反而需要显示重写。

接口或者抽象类定义了必须实现的规范。Python中的规范是通过人有意识来实现。接口、抽象类是通过编程实现的。如果通过功能约束则需要较高的编程能力。

这是一个接口的例子,如果不实现会报:AttributeError: Foo instance has no attribute \'bar\'

依赖zope接口规范库,需要pipTwisted

 

抽象类,不实现:TypeError: Can\'t instantiate abstract class Worker with abstract methods talk

 

 

Scala

Scala方法和函数是有区别的。详细介绍点击这里

本文中的目录结构

下面的例子介绍scala实现单例的过程,其中涵盖scala的编程特点。

在包oop.example下新建一个scala文件。

在这个文件中写个Worker类,类上是个主构造方法,访问权限是私有。参数:名字和外号。

定义个从构造方法,没有具体意义。

重载toString()方法

在同一文件中定义伴生对象

定义一个静态私有常量instance,其它不重要用于演示的成员。

获取单例对象的方法。至此一个单例就完成了。

通过Worker既能访问伴生对象(静态)方法、属性,通过getInstance()也能获取类单例对象实例。

 

Scala中的接口和继承。

Scala是单继承,否则错误提示:class Other needs to be a trait to be mixed in。

Scala可以继承多个特质,而特质类似java8中接口,可以定义多个方法,从而实现多继承。其它可以参照java实现多继承。

在package oop.example下任意新建个scala文件。

这里定义特质 Person,Studnet

特质用trait关键字,: 冒号后面指返回值,Unit同void。

抽象类Coder继承多个特质。

这里函数一般定义 val 函数名 = (参数列表1-22) => 函数体,不用声明返回值类型,因为是确定的。

 

接下来介绍scalapackage object对象。详情点击这里

Package提供了一个命名扩展。会首先编译,如果出错,其它scala文件将执行不了。

 

则可以这么使用

结果:

type oop.example.Me起个别名,这里是因为路径太长。目的如果Me路径改变了,通过原先路径(别名)照成访问。

package scala中可以定义classobject对象。

下面是个scala高阶函数的例子。Object类型不用对static考虑,减少设计负担。

这是一个延时执行方法例子。参数是方法。

object Xxx main方法执行

结果

下面是个高级函数例子

applyXf(v),f为方法,v是参数。

方法可以没有参数列表即(),函数必须有()

 

Go

Go语言之父,设计go语言设计目标的演讲。点击这里。或者复制下面链接http://www.csdn.net/article/2012-07-05/2807113-less-is-exponentially-more

核心思想:Less can be more!并行性,类似软管拼接的编程体验。

Go语言语法简单,例子中介绍

声明一个接口,这个接口是方便在hi.go中测试。

定义通道syn保证Init方法与Test方法同步执行

所有的测试文件在src/oop目录下,在hi.go中引入,

要测试的go语言特性。

要测试的几个文件都实现了oop.Test接口

 

Go语言公有的访问权限是首字母大写,否则将编译报错

 

闭包特性

 

继承例子

Go继承是通过组合

 

Go并发特性

 

 

一个并发池的例子

通道概念

一个死锁例子

通过go 并发解决这个问题

或者改为缓存通道

 

 

Java实现多继承

Java一般通过组合和接口实现多继承。因为接口是可以多继承的,在接口的实现中调用其它类对象的方法。

定义两个接口分别是ActionArt,表示物理上的行为和隐含的需要理解感受的行为。

自然界的动物继承Action行动,Art感染力。

人类,直接实现Animal接口实现多继承。但这样需要自定义实现。

另外一种使用场景,一些方法是确定的,另外一些不确定。所有鸟的例子。

具体哪种鸟不一定,比如会抽烟、会唱歌的鸟。

一只参与京剧表演的老鹰

一个非常善于学习的人,会多种技巧。

 

Java闭包实现

java闭包是通过接口和私有内部类实现的。利用java的运行时多态,接口引用实现类的。返回实现接口的私有内部类实例实现的。

接口Worker表示所有的工作者,方法work表示不同的工作形式。

软件程序设计者

软件开发者,熟练get各种技能

资深Coder除了进行简单必要的软件设计,还要有其它技能:交流、管理。这个Coder的黑科技是加班。

这个已经能访问到私有对象。

一个方法多种实现

以上是关于面向对象的主要内容,如果未能解决你的问题,请参考以下文章

224 面向对象编程介绍,面向过程与面向对象

面向对象-面向对象和面向过程的区别

面向对象分析与设计面向对象设计包括哪些内容

面向对象

面向过程面向对象及面向对象的三大特征

Python面向对象学习 1 (什么是面向对象,面向对象的应用场景)