谈谈我对面向对象以及类与对象的理解

对于刚接触JAVA或者其他面向对象编程语言的朋友们来说,可能一开始都很难理解面向对象的概念以及类和对象的关系。笔者曾经带过一个短期培训班教授java入门基础,在最后结束课程的时候,还有很多同学不太理解面向对象的思维以及类与对象的意义。这几天有空,就想着整理整理自己的思路,谈谈自己对面向对象以及类与对象的理解。

面向对象

首先,一言不和先百度,得到如下定义:

一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。

我们知道,编写程序的目的是为了解决现实生活中的问题,编程的思维方式也应该贴近现实生活的思维方式。面向对象的编程方式就是为了实现上述目的二出现的。它使得编程工作更直观,更易理解。需要注意的是这里说的编程不光是coding还包括了设计的过程也是面向对象的

为什么说面向对象更贴近实际生活

想象一下,当我们向别人描述一样事物时,我们都是怎么说的?"它有像鸭子一样的嘴巴","它有4条退","爪子里还有蹼","它是哺乳动物但却是卵生"。

这种HAS A 和 IS A的表达方式往往可以简单而高效的描述一样事物。HAS A描述事物的属性或行为,IS A 则说明了事物的类属。

当我们把这一系列的属性组合起来便得到的鸭嘴兽这一类,同时哺乳动物一词简单精炼的表面了所有哺乳动物的特性而不用一一列出,这是继承特性的体现,同时卵生又是多态的体现。

这就是面向对象的思维特点,抽取(抽象)有用的属性和行为(抛弃哪些无需关系的)组织(封装)成一个类。这个过程中你也许会发现很多属性或方法是和另一个类相同的,那么你就可以采用继承的方式避免重复(当然这个过程也有可能是,当你设计完一个个类后,才发现他们有共同点,然后再抽取出基类)。更重要的是,继承是可以不原样照搬的,我们可以通过重载实现相同行为或属性的特有实现方式,这种特点称之为多态,例如同样的生产行为,实现方式由胎生变为卵生。请大声念出,并牢牢记住面向对象的四个特征:

  • 抽象
  • 封装
  • 继承
  • 多态

与早期结构化编程相比

早期结构化编程是面向过程的(功能),换句话说程序是由功能的集合组成,而调用者是作为功能的参数传入的。而在面向对象的程序中,对象是主体,程序是由对象的集合组成。一个对象中包含一系列符合设计的功能供其他对象调用。这么说可能还是比较抽象,

例如当我们设计一个五子棋游戏时,面向过程的设计思路就是首先分析问题的步骤:

1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。

把上面每个步骤用分别的函数来实现,问题就解决了。

而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:

1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。

第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

(以上例子来自国内著名问答社区)

随便写点代码,大家看看就好,不要太认真....


  1. /** 
  2. 玩家类 
  3. **/ 
  4. public class Player { 
  5.     String name;       //棋手名称 
  6.     boolean isFirst;  //是否先手 
  7.     int color_flag;  //代表颜色  0-白 1-黑 
  8.     Table table;//棋盘对象 
  9.      
  10.     public Player(String name,boolean isFirst;int color_flag){ 
  11.              this.name=name; 
  12.              this.isFirst=isFirst; 
  13.              this.color_flag=color_flag; 
  14.       } 
  15.     
  16.     /** 
  17.     下棋,x,y为落子坐标 
  18.     **/ 
  19.     public void play(int x,int y) throws Exception{ 
  20.       if(this.table==null){ 
  21.          throw new IllegalArgumentException("玩家还未注册到棋盘!"); 
  22.       } 
  23.       table.setNewPieces(x,y); 
  24.     } 
  25.      
  26.     public void setTable(Table table){ 
  27.        this.table=table; 
  28.     }  
  29. /** 
  30. 棋盘类 
  31. **/ 
  32. public class Table{ 
  33.   List<Player> playerList=new ArrayList<Player>(); 
  34.   Referee referee ; 
  35.   public Table(){ 
  36.    referee =new Referee(this); 
  37.   } 
  38.   /** 
  39.     注册玩家 
  40.   **/ 
  41.   public void registPlayer(Player player) throws Exception { 
  42.       //检测棋盘中的玩家是否已满,先手玩家和玩家选色是否冲突。 
  43.       ....... 
  44.      playerList.add(player); 
  45.      player.setTable(this); 
  46.   } 
  47.  
  48.    /** 
  49.     落子 
  50.    **/ 
  51.  
  52.    public void setNewPieces(int x , int y){ 
  53.           //重新绘制棋盘 
  54.           ...... 
  55.          //调用裁判对象,判断结果 
  56.       if(referee.isEnd){ 
  57.           End(); 
  58.         } 
  59.    } 
  60.  
  61.    public void End(){ 
  62.       ....... 
  63.   } 
  64. /** 
  65. 裁判类 
  66. **/ 
  67. public class Referee(){ 
  68.   Table table; 
  69.   public Referee(Table table){ 
  70.     this.table=table; 
  71.  } 
  72.  
  73.    public boolen isEnd(){ 
  74.       //判断输赢 
  75.       .... 
  76.     return false;  
  77.    } 
  78. }  

然而事实上,通过上述示例代码,我们不难发现,即使我们使用面向对象的方式,上面例子里面向过程中提到的几个下棋过程我们还是都实现了的,只不过程被封装到了类的方法中。所以说其实面向对象和面向过程并不是编程的区别(需要实现的业务逻辑的量不会产生变化),而是设计的区别!

类与对象

类是抽象的,而对象是具体的

如何理解上面的话呢? 例如鸭嘴兽是类型,具体的鸭嘴兽A、鸭嘴兽B就是对象了。在JAVA中对象是通过new关键字声明的。 再例如,《红色警戒》中美国大兵是一类兵种,点击制造后从兵营里出来的那个会开枪的家伙就是对象了:

类的定义就是一个模板,它描述的一类对象的属性与行为。类往往是抽象的、没有实体的。哺乳动物是类的概念,是抽象的,现实中没有哺乳动物这一实体,只有具体的如老虎,狮子等。编程工作中套用这一思维模式,我们将程序中的实例抽象为类,例如一个系统中的用户有张三、李四我们会把他们抽象为Person类,或者称之为一个名为Person的数据类型。

对象则是根据所属类模板创造出来的实实在在的事物。在程序中我将这个实实在在的事物称之为实例,我们为它的属性赋上特定的值,让它成为张三或者李四。在内存里来说,对象是表示的就是具体数据。

前面说的都是概念性的东西,下面我们说说实际的运用过程中的理解。

从数据类型来说

以java为例,数据类型分为基本数据类型和引用数据类型。

基本数据类型就是byte,short,int,long,double,char,boolean;其它的,需要用到new关键字来赋值的都是引用数据类型。
类与对象指的便是引用数据的类型与其值(这里指的类不光是class,还包括接口、数组、枚举、注解)。
而引用指的是内存地址的引用,关于这点在后面说的内存时会细说。

看下面的代码:


  1. int a =1; 
  2.  
  3. 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)中,例如当如下代码:


  1. int a=1; 
  2.  
  3. Person p;  

内存中的状态大致如下:

int a = 1 是直接在栈中开辟空间,而对于未进行实例化的Person p因为没有有效的内存地址引用它的值是null。而当代码进行如下修改时:


  1. int a =1 ; 
  2.  
  3. Person p = new Person();  

内存中的状态大致如下:

Person p=new Person();使得p的值=0x8da23也就是对象new Person();在堆中的地址。所以,到这里后就不难理解之前说的对象的引用了,所谓引用其实就是堆内存地址的引用。

总结

随着计算机技术的不断提高,现在计算机不单单是用来解决运算问题,而是被用于解决越来越贴近现实生活的复杂问题。面向对象就是这一发展进程的产物,它使得编程工作更贴近人的思维方式,从而大大提升编程效率。我们必须明白的是面向对象并不是一种编程方式,而是一种编程思维方式,这种思维方式涵盖了分析,设计,编码等。在面向对象编程中,程序的基本单元是对象,数据封装在对象中。类是对象模板,是预定义好的结构,所谓的实例化一个类,所指的就是将数据填入模板。

最后,本人文笔不是很好,有待提高。写文章和博客的最大目的是梳理自己的思路,其二是分享自己的想法,望大家多多吐槽,愿共同提高。

作者:justin890215

来源:51CTO

时间: 2024-09-19 09:04:45

谈谈我对面向对象以及类与对象的理解的相关文章

javascript面向对象——定义类或对象的几种方式

从语言的视角看,面向对象的编程和面向对象的javascript绝对不是什么现代的东西:从刚开始javascript就被全面的设计为面向对象的语言 下面呢,就介绍一下,定义类或对象的几种方式: 1 工厂模式 代码如下 function createcar(iColor,iDoors,iMpg) { varoTemCar = new Object; oTemperCar.color = iColor; oTemperCar.doors = iDoors; oTempCar.mpg = iMpg; o

php (十一) 面向对象 通过类实例化对象

1. 实例化对象       当定义好类后,我们使用new关键字来生成一个对象.  $对象名称 = new 类名称(): 示例:       [php]  <span style="color:#333333;"><?php   class Person   {   //下面是人的成员属性   var $name;     //人的名子       var $sex;      //人的性别   var $age;      //人的年龄   //下面是人的成员方法

深入Objective-C Runtime机制(一):类和对象的实现

1.概要      对于Runtime系统,相信大部分iOS开发工程师都有着或多或少的了解.对于Objective-C,Runtime系统是至关重要的,可以说是Runtime系统让Objective-C成为了区分于C语言,C++之外的一门独立开发语言,让OC在拥有了自己的面向对象的特性以及消息发送机制.并且因为其强大的消息发送机制,也让很多人认为Objective-C是一门动态语言(实际上每种语言都具有一定的动态性,只是OC的Runtime更加强大,但它仍比不上Python,Lua等动态语言).

《Java程序员面试秘笈》—— 面试题5 用自己的语言描述Java中的类和对象

面试题5 用自己的语言描述Java中的类和对象 下列关于对象的哪一种说法是正确的?请选择一个正确的答案. (a)对象是可以对其进行实例化从而得到类的东西. (b)对象是类的实例. (c)对象是一种蓝本,据此可以创建抽象的具体实现. (d)对象是指向属性的引用. (e)对象是一种变量. 考点:该面试题考察求职者对于Java类和对象的理解. 出现频率: [面试题解析] 1.类 在处理复杂事物的时候,用到的一种基本手段就是抽象.抽象的目的就是区别事物之间的本质和不同,面向对象编程(OOP)的实质就是利

全面理解Java类和对象_java

面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分.在面向对象程序设计(OOP)中,不必关心对象的具体实现.在传统的结构化程序设计中,算法是第一位的,数据结构是第二位的,即首先确定如何操作数,再考虑如何组织数据,以方便操作.而OOP则颠倒了这种次序,将数据放在第一位,然后再考虑操作数据的算法. 一.类 类是构造对象的模板和蓝图.通俗地说,类相当于建筑的图纸,而对象相当于建筑物.由类构造对象的过程称为创建对象的实例. Java中通过关键字class定义"类"

PHP面向对象编程详解:类和对象

PHP面向对象编程详解:类和对象 从OOP的视角看,不应区分语言.无论是C++.无论是Java.无论是.net还有更多面向对象的语言,只要你了解了OO的真谛,便可以跨越语言,让你的思想轻松的跳跃.便没有对于Java..net.PHP 之间谁强谁弱的争执了. 希望这个介绍PHP5面向对象编程(OOP)的资料能让初学者受益,能让更多的PHPer开始转向OO的编程过程. 相对PHP4,PHP5在面向对象方面改变了很多.我们将只介绍PHP5环境下的面向对象.而我们必须改变自己来跟随PHP5的发展.如果代

Java千百问_05面向对象(001)_类、对象到底有什么秘密

1.类.对象的概念是什么 Java是目前应用最为广泛的面向对象特的语言,它具有以下基本概念: 类 对象 方法 抽象化 多态性 继承 封装 我们首先看看类和对象的概念. 类 类是一个模版.是一个可以定义一类具有相同属性.行为的模版.  例如:狗是一个类,它具有四肢.尾巴.头.脊椎等属性,具有吠叫.吃.繁殖等行为. 对象 对象是一个具体实例.根据是一个类的具体实例.  例如:我家对门养的一只狗,具体到了某一只. 2.Java如何定义类 类的定义如下︰ public class Dog{ String

面向对象程序设计上机练习七(类和对象)

面向对象程序设计上机练习七(类和对象) Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 利用类的数据成员和成员函数完成下列操作:输入三个整数,输出它们的最大值. Input 输入三个整数. Output 输出3个整数的最大值. Example Input 2 8 5 Example Output 8 Code realization #include <iostream> using n

面向对象程序设计上机练习五(类和对象)

面向对象程序设计上机练习五(类和对象) Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 定义类Time,Time有3个公用的数据成员hour.min.sec分别表示小时.分.秒. 在主函数main中定义Time类对象t1,在主函数main中输入t1的各数据成员再并输出各数据成员. Input 输入类对象的3个数据成员hour.min.sec. Output 输出类对象的3个数据成员hour