文章最初发表于个人我的博客非典型性程序猿java
对于刚接触JAVA或者其余面向对象编程语言的朋友们来讲,可能一开始都很难理解面向对象的概念以及类
和对象
的关系。笔者曾经带过一个短时间培训班教授java入门基础,在最后结束课程的时候,还有不少同窗不太理解面向对象
的思惟以及类
与对象
的意义。这几天有空,就想着整理整理本身的思路,谈谈本身对面向对象以及类与对象的理解。编程
首先,一言不和先百度,获得以下定义:数组
一切事物皆对象,经过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。jvm
咱们知道,编写程序的目的是为了解决现实生活中的问题,编程的思惟方式也应该贴近现实生活的思惟方式。面向对象的编程方式就是为了实现上述目的二出现的。它使得编程工做更直观,更易理解。须要注意的是这里说的编程不光是coding还包括了设计的过程也是面向对象的编程语言
想象一下,当咱们向别人描述同样事物时,咱们都是怎么说的?"它有像鸭子同样的嘴巴","它有4条退","爪子里还有蹼","它是哺乳动物但倒是卵生"。函数
这种HAS A
和 IS A
的表达方式每每能够简单而高效的描述同样事物。HAS A
描述事物的属性或行为,IS A
则说明了事物的类属。布局
当咱们把这一系列的属性组合
起来便获得的鸭嘴兽这一类
,同时哺乳动物
一词简单精炼的表面了全部哺乳动物的特性而不用一一列出,这是继承
特性的体现,同时卵生
又是多态
的体现。this
这就是面向对象的思惟特色,抽取(抽象
)有用的属性和行为(抛弃哪些无需关系的)组织(封装
)成一个类。这个过程当中你也许会发现不少属性或方法是和另外一个类相同的,那么你就能够采用继承
的方式避免重复(固然这个过程也有多是,当你设计完一个个类后,才发现他们有共同点,而后再抽取出基类)。更重要的是,继承是能够不原样照搬的,咱们能够经过重载
实现相同行为或属性的特有实现方式,这种特色称之为多态
,例如一样的生产行为,实现方式由胎生变为卵生。请大声念出,并紧紧记住面向对象的四个特征:编码
抽象spa
封装
继承
多态
早期结构化编程是面向过程的(功能),换句话说程序是由功能的集合组成,而调用者是做为功能的参数传入的。而在面向对象的程序中,对象是主体,程序是由对象的集合组成。一个对象中包含一系列符合设计的功能供其余对象调用。这么说可能仍是比较抽象,,例如当咱们设计一个五子棋游戏时,
面向过程的设计思路就是首先分析问题的步骤:
一、开始游戏,二、黑子先走,三、绘制画面,四、判断输赢,五、轮到白子,六、绘制画面,七、判断输赢,八、返回步骤2,九、输出最后结果。
把上面每一个步骤用分别的函数来实现,问题就解决了。
而面向对象的设计则是从另外的思路来解决问题。整个五子棋能够分为:
一、黑白双方,这两方的行为是如出一辙的,二、棋盘系统,负责绘制画面,三、规则系统,负责断定诸如犯规、输赢等。
第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行断定。
(以上例子来自国内著名问答社区)
随便写点代码,你们看看就好,不要太认真....
/** 玩家类 **/ public class Player { String name; //棋手名称 boolean isFirst; //是否先手 int color_flag; //表明颜色 0-白 1-黑 Table table;//棋盘对象 public Player(String name,boolean isFirst;int color_flag){ this.name=name; this.isFirst=isFirst; this.color_flag=color_flag; } /** 下棋,x,y为落子坐标 **/ public void play(int x,int y) throws Exception{ if(this.table==null){ throw new IllegalArgumentException("玩家还未注册到棋盘!"); } table.setNewPieces(x,y); } public void setTable(Table table){ this.table=table; } } /** 棋盘类 **/ public class Table{ List<Player> playerList=new ArrayList<Player>(); Referee referee ; public Table(){ referee =new Referee(this); } /** 注册玩家 **/ public void registPlayer(Player player) throws Exception { //检测棋盘中的玩家是否已满,先手玩家和玩家选色是否冲突。 ....... playerList.add(player); player.setTable(this); } /** 落子 **/ public void setNewPieces(int x , int y){ //从新绘制棋盘 ...... //调用裁判对象,判断结果 if(referee.isEnd){ End(); } } public void End(){ ....... } } /** 裁判类 **/ public class Referee(){ Table table; public Referee(Table table){ this.table=table; } public boolen isEnd(){ //判断输赢 .... return false; } }
然而事实上,经过上述示例代码,咱们不难发现,即便咱们使用面向对象的方式,上面例子里面向过程当中提到的几个下棋过程咱们仍是都实现了的,只不过程被封装
到了类的方法中。因此说其实面向对象和面向过程并非编程的区别(须要实现的业务逻辑的量不会产生变化),而是设计的区别!
类是抽象的,而对象是具体的
如何理解上面的话呢? 例如鸭嘴兽是类型,具体的鸭嘴兽A、鸭嘴兽B就是对象了。在JAVA中对象是经过new
关键字声明的。 再例如,《红色警惕》中美国大兵是一类
兵种,点击制造后从兵营里出来的那个会开枪的家伙就是对象
了:
类
的定义就是一个模板,它描述的一类对象的属性与行为。类每每是抽象的、没有实体的。哺乳动物是类
的概念,是抽象的,现实中没有哺乳动物这一实体,只有具体的如老虎,狮子等。编程工做中套用这一思惟模式,咱们将程序中的实例抽象为类,例如一个系统中的用户有张3、李四咱们会把他们抽象为Person类,或者称之为一个名为Person的数据类型。
对象
则是根据所属类
模板创造出来的实实在在的事物。在程序中我将这个实实在在的事物称之为实例,咱们为它的属性赋上特定的值,让它成为张三或者李四。在内存里来讲,对象是表示的就是具体数据。
前面说的都是概念性的东西,下面咱们说说实际的运用过程当中的理解。
以java为例,数据类型分为基本数据类型
和引用数据类型
。
基本数据类型就是byte,short,int,long,double,char,boolean
;其它的,须要用到new
关键字来赋值的都是引用数据类型。 类与对象指的即是引用数据的类型与其值(这里指的类不光是class
,还包括接口、数组、枚举、注解
)。 而引用指的是内存地址的引用,关于这点在后面说的内存时会细说。
看下面的代码:
int a =1; Person b=new Person();
a 和 b 都是自己无心义的变量名。须要关注的是:a的类型是基本数据类型int值为1,而b的类型是Person属于引用类型,其引用的是new Person()这个对象。咱们每每会说对象xx,好比这里的对象b。但实际上b只是对象的引用,真正的对象是后面的new Person()!
须要注意的是String也是引用数据类型,只不过由于使用率很是高,因此对于String,jvm支持其可 以像基本数据类型同样使用:String a = "abc"; 同等于 String a = new String("abc");
总之呢,简单来讲类
指的的引用数据的类型,对象
是具体赋的值。为了更深刻理解,咱们下面须要解释下这个引用
是如何体现的。
要深刻理解什么是类,什么是对象,什么又是引用,就离不开说说java的内存使用方式。
在java中内存被大体划分为栈(stack)
与堆(heap)
(之因此是大体,是由于还包括其它几部分就不在这细说)。
关于什么是栈与堆在这就不细说,有空我再整理一篇文章详细说明。
在这里咱们只说一点:java中,基本数据类型以及对象的引用都保存在栈(stack)
,而对象则保存在堆(heap)
中,例如当以下代码:
int a=1; Person p;
内存中的状态大体以下:
int a = 1 是直接在栈中开辟空间,而对于未进行实例化的Person p由于没有有效的内存地址引用它的值是null。而当代码进行以下修改时:
int a =1 ; Person p = new Person();
内存中的状态大体以下:Person p=new Person();
使得p的值=0x8da23也就是对象new Person();
在堆
中的地址。因此,到这里后就不难理解以前说的对象的引用了,所谓引用其实就是堆内存地址的引用。
随着计算机技术的不断提升,如今计算机不仅仅是用来解决运算问题,而是被用于解决愈来愈贴近现实生活的复杂问题。面向对象就是这一发展进程的产物,它使得编程工做更贴近人的思惟方式,从而大大提高编程效率。咱们必须明白的是面向对象并非一种编程方式,而是一种编程思惟方式,这种思惟方式涵盖了分析,设计,编码等。在面向对象编程中,程序的基本单元是对象
,数据封装在对象中。类
是对象模板,是预约义好的结构,所谓的实例化一个类,所指的就是将数据填入模板。
最后,本人文笔不是很好,有待提升。写文章和博客的最大目的是梳理本身的思路,其二是分享本身的想法,望你们多多吐槽,愿共同提升。