深入分析面向对象中的对象概念

  OOP:面向对象编程,一提到面向对象,大家可能就想到类,接口。一说特性,大家可能张口就来:继承、封装、多态,那么到底什么样的对象(类)才是真正意义上的对象呢?特别是现在流行的DDD领域驱动设计思想,讲究职责划分,那么如何定义一个对象(类)它应该具有的一些特性、行为方法及承担责任成为关键。

  一个看似简单的问题,其实也是耐人思索,之前也在网上看到一些人关于讨论类的设计问题,认为设计类时不应该考虑数据库,我觉得这只是实现真正的面向对象设计的基础,也是前提条件,大多数程序员之前都是受面向过程编程思想的影响,我(梦在旅途)也不例外,一个需要求下来,首先就是想它需要存哪些数据,建哪些表,要定义哪些个方法来完成数据的存储,整个过程基本是围绕数据库来进行的,我这里称之为数据驱动编程,这样开发其实也没有错,因为存在即有存在的道理,我也可以分析出这种编程的优点:开发速度快,执行效率高(没有层级或层级之前只是简单的转发),缺点是:可读性差,不利于后续的二次开发等,简单的应用程序或某个独立的核心模块使用这种编程方式我觉得也是可以的,但除此之外,我仍觉得合理的面向对象是有必要的,我这里强调合理,是不要一味的盲目采用某个框架或某种设计模式,没有最好的框架,同样也没有最好的设计模式,唯有最适合的框架与设计模式,那么如何评估框架与设计是否合适,我认为对象(类)的设计至关重要,下面就我的经验及我所看到的现象来谈谈的对象的设计问题,由于我不是什么大牛,所以难免表达有误的地方,请多包涵,当然也欢迎大家一起讨论。

1.对象是什么?

在现实生活中,对象指的是某一个客观存在的事物,它具有能识别它唯一性的属性,比如:某人的某个品牌的某个型号的汽车,我这里为什么用了多个某个,因为人+品牌+型号+汽车,就能确定具对这个对象,而不是汽车这么简单,注意汽车并不是一个对象,它只是表示的是某类事物,所以通过现实生活的分析,我们可以转换思想到编程的世界中,来分析对象与类的区别。在编程中,类就是上面的汽车,而对象则是类的实例化,识别对象的唯一性从计算机的角色讲,应该是内存堆中地址,每一个地址确定一个对象。

2.对象有什么?

对象指的是具体的某个事物,除了有识别它唯一性的属性外,它应该还有以下几个特性:

一、状态(也可以简单的称之为属性):描述一个对象的特征,这个特征可以永久的,也可以是受外界影响而改变的,比如:某人的某个品牌的某个型号的汽车,如果这辆车重新喷漆,换了一种颜色,那么的它此时的状态,颜色被改变;如果车被卖给另外一个人,那么它此时的状态,车的所有者也被改变了。

代码示例:

    public class Car //这是一个类
    {
        public Car(string owner,string brand,string model,string color)
        {
            this.Owner = owner;
            this.Brand = brand;
            this.Model = model;
            this.Color = color;
        }

        public string Owner { get; set; }

        public string Brand { get; set; }

        public string Model { get; set; }

        public string Color { get; set; }
    }

        public static void Main(string[] args)
        {
            var car = new Car("张三", "宝马", "B01", "黑色");//这是一个对象
            car.Color = "红色";//状态被改变
            car.Owner = "李四";//状态被改变
        }

二、行为(也可以简单的称之为方法、函数):一个对象主动或被动去执行某种动作,比如:张三这个人,他吃饭,他看书,他睡觉等都是一种行为,包括我现在写博客也是一种行为。行为又分主动与被动,主动是指一个对象主观意识的动作,比如:张三吃饭就是主动,而被动则是需另一个对象来命令它来执行某种动作,比如:汽车启动,启动是一个行为,但它不能自己启动,需要驾驶人去通过汽车给定的启动方法与步骤来请求汽车执行启动,又或者说是取款机,取款机提供一个取款的行为,而具体什么时候来取,取多少,均由人来告诉它。

代码示例:

    public class Car //这是一个类
    {
        public Car(string owner,string brand,string model,string color)
        {
            this.Owner = owner;
            this.Brand = brand;
            this.Model = model;
            this.Color = color;
        }

        public string Owner { get; set; }

        public string Brand { get; set; }

        public string Model { get; set; }

        public string Color { get; set; }

        public string Status { get; private set; }

        public Driver Driver { get; set; }

        public void Start() //启动方法,被动
        {
            if (this.Driver!=null)
            {
                this.Status = "运行中";
            }
            else
            {
                throw new InvalidOperationException("没有驾驶员,不能自动启动!");
            }
        }

        public void Stop() //启动方法,被动
        {
            this.Status = "停止";
        }
    }

    public class Driver
    {
        public string Name { get; set; }

        public Driver(string name)
        {
            this.Name = name;
        }

        public void  Drive(Car car)//驾驶,主动
        {
            car.Driver = this; //坐在车上
            car.Start();//启动汽车,并运行
            car.Stop();//到达终点,停止汽车
        }
    }

    public class APP9
    {
        public static void Main(string[] args)
        {
            var car = new Car("张三", "宝马", "B01", "黑色");//这是一个对象
            var driver = new Driver("李四");
            driver.Drive(car);//李四来开张三的车,现实生活中不能随便借车开哦!~V~
        }
    }

有人看了上面的代码后,可能再想,不是所有的对象都有行为吧,既然是行为,行为又代表一种动作,那么也只有能动的对象才有行为,不能动的对象就没有,是这样吗?我在写这篇博文前也思考了这个问题,开始也这样认为的,后面仔细一想,不对,应该是所有的对象都有行为,就拿不动的东西来说吧,比如一张纸,纸本身本是不能动的,但如果你把它扔起来,那么纸就具备了被动的移动方法,根据爱因斯坦的相对论,没有绝对的静止,只有相对的静止,所以就看在什么情况下,参照物是什么,有点扯远了哈,回归正题,有人可能还是不服,所有的对象都有行为方法,那我不是非要对所有的类都定义方法吗,不然就不符合真正的对象?我认为不是这样的,场景决定一个对象的状态与方法,这也是下面我将要说明的角色定位的问题,这里我可以很负责任的告诉你,我们所有的定义的对象都有行为,只是你没有意识到而矣,是什么呢?那就是构造函数与析构函数,它们就是被动的行为方法,这也是符合现实生活的对象,任何一个对象都有创建与毁灭,你敢说不是吗?请举出例子来吧!

3.对象角色定位

任何一个对象在不同的场景中应该有不同的状态及行为,比如:张三,张三在学校他是学生,具有学生的状态及行为,在公司工作他是员工,具有员工的状态及行为,取得驾照驾驶汽车,具备驾驶员的状态及行为,在图书馆看书,具备读者的状态与行为。由此可知,对象是复杂的,类是具体一些,对象存在多变性,而类则应具备不变性,可能有人不明白,我这里具体解释一下,我这里说的可变性,不是面向对象的那个多态,而是指对象角色的可变性,比如:学生类,那么它就表示学生,它不可能还表示作者,当然它可以表示人,但一般人不会这样表示,而对象则不同,正如上面我讲的张三的不同角色,他不同类的实例化,类不支持多重继承,我觉得对的,因为一个类可以代表一个角色,一个角色只能做这个角色的事情,比如:学生,他就是学习,老师,他就是教书,有人可能还会说,兼职多个角色,又是员工又是驾驶员,又是老师同时又是学生,是的,确实存在,但上面说过了,兼职的时候一个对象不可能同时做某个事情,比如:又是员工又是驾驶员,难道他同时工作又同时开车,有人说:出租车司机呀!好吧,你历害,但仍然是角色不同,出租车司机开车就是工作,当他不工作开车时,他就是驾驶员。好了,说了这么多,看是来看一下代码示例吧!

    public class Person //人
    {
        public string IdNo{get;set;}

        public string Name { get; set; }

        public string Sex { get; set; }

        public double Height { get; set; }

        public double Weight { get; set; }

        public DateTime BirthDay { get; set; }

    }

    public class Post //文章
    {

        public string Title { get; set; }

        public string Content { get; set; }

        public Author Author { get; set; }

        public DateTime CreateDatetime { get; set; }

    }

    public class Author : Person //角色为作者
    {
        public void Write(Post post)
        {
            //行为
        }
    }

    public class Book //书
    {
        public string Name { get; set; }

        public DateTime IssuedDate { get; set; }

        public List<Post> Posts;

    }

    public class Library //图书馆
    {
        public string Name { get; set; }

        public List<Book> Books { get; set; }

        public void Borrow(Reader reader, IEnumerable<Book> books) //借出书,被动
        {
            Books.RemoveAll(b=>books.Contains(b));
            //其它操作
        }

        public void Return(Reader reader,IEnumerable<Book> books)//还入书,被动
        {
            Books.AddRange(books);
            //其它操作
        }
    }

    public class Reader : Person //角色为读者
    {
        public List<Book> Books { get; set; }

        public IEnumerable<Post> Read(Book book,params int[] pages) //读书,主动
        {
            var posts = new List<Post>();
            if (pages != null)
            {
                foreach(int i in pages)
                {
                    posts.Add(book.Posts[i]);
                }
            }
            else
            {
                posts = book.Posts;
            }
            return posts;
        }

        public void Borrow(IEnumerable<Book> books, Library library) //主动借书
        {
            library.Borrow(this,books);
            Books.AddRange(books);
        }

        public void Return(IEnumerable<Book> books, Library library)//主动还书
        {
            library.Return(this, books);
            Books.RemoveAll(b => books.Contains(b));
        }

    }

    public class Driver:Person //角色为驾驶员
    {
        public void Drive(Car car)
        {
            car.Driver = this;
            car.Start();
            car.Stop();
        }
    }

    public class Car
    {
        public Driver Driver { get; set; }

        public string Status{get;private set;}

        public void Start()
        {
            this.Status="运行中";
        }

        public void Stop()
        {
            this.Status="停止";
        }
    }

结 尾

我这里只是定义,没有列出运行时代码。例子比较简单,大家看一下就好了。最后要说明的是,对象虽然都有状态与行为,而且角色不同状态与行为也随之不同,但在编程的世界里,我们可以只关注我们所关注的,比如:一个博客系统,我们只关注作者,阅读者,回复者三个角色,从这三个角色应该具备的状态与行为进行设计相关的类,这样就比较符合真实的对象了,也就不会出现大家常见的:状态类-僵尸类(只有属性,无方法),方法类-孤魂野鬼类(只有方法,无属性)


好了,文章到这里就结束了,面向对象的思想博大精深,很难一下子全部说明白,但相信只要我们在编程中多思考多总结就能提升我们编程觉悟,有朝一日成为大师。在此向大师、大牛们致敬,向你们学习,学习的道路永远止境。这篇文章我花了一上午的时间,想了很多,写得却不是很多,但都是源自我的想法,如果帮助到大家了,还请支持推荐一下哦,非常感谢!

时间: 2025-01-13 22:04:34

深入分析面向对象中的对象概念的相关文章

深入分析面向对象中的对象概念(转)

OOP:面向对象编程,一提到面向对象,大家可能就想到类,接口.一说特性,大家可能张口就来:继承.封装.多态,那么到底什么样的对象(类)才是真正意义上的对象呢?特别是现在流行的DDD领域驱动设计思想,讲究职责划分,那么如何定义一个对象(类)它应该具有的一些特性.行为方法及承担责任成为关键. 一个看似简单的问题,其实也是耐人思索,之前也在网上看到一些人关于讨论类的设计问题,认为设计类时不应该考虑数据库,我觉得这只是实现真正的面向对象设计的基础,也是前提条件,大多数程序员之前都是受面向过程编程思想的影

深入分析面向对象中的封装作用

之前我(梦在旅途)发表过一篇名为<深入分析面向对象中的对象概念>的文章,里面主要讲解了类与对象的关系以及对象的概念.状态.行为.角色几个知识点,让大家对对象有了一些深入的了解,而本文则再来谈谈面向对象的三大特性之一:封装,封装是实现面向对象的基础,深入的理解封装的特性,有利于我们能更好的领悟面向对象的思想以及实现面向对象编程.以下均为本人凭借多年开发经验总结的个人观点,大家若发现有误或不足的地方,欢迎指正和交流,谢谢! 一.什么是封装? 顾名思义,封:封闭,装:装起来,将具体的实现细节装到一个

面向对象中的一些概念的理解

今天回顾的内容,可能相对于前面的内容来说在理解上需要花费一点功夫,但面向对象也是属于打基础的部分,学好虽然不能够加分,但是没有掌握到这方面的知识,在后续的基础学习中,会有一些问题.那,我们开始回顾今天的内容吧!! 1. 构造方法 特点:与类同名而没有返回值类型 作用:创建对象 package cn.tedu.object; public class PersonDemo { public static void main(String[] args) { //构造方法 --- 创建对象的 //调

js面向对象学习 - 对象概念及创建对象

原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数据属性和访问器属性. 1.数据属性又包含 Configurable //表示能否通过delete删除,默认为true: Enumerable //表示能否通过for-in循环返回属性,默认为true; Writable  //表示能否修改属性的值,默认为true; Value            

PostgreSQL中几个对象概念及其关系

本文参考:http://blog.csdn.net/kanon_lgt/article/details/5931522 http://blog.csdn.net/kanon_lgt/article/details/6220928 DB实例与schema: 模式是数据库实例的逻辑分割. 数据库是被模式(schema)来切分的,一个数据库至少有一个模式,所有数据库内部的对象(object)是被创建于模式的.用户登录到系统,连接到一个数据库后,是通过该数据库的search_path来寻找schema的

JS中面向对象的,对象理解、构造函数、原型、原型链

6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性.对象上定义的属性默认值为true [[enumerable]] 表示能否通过for-in循环返回属性.直接在对象上定义的属性,它们的这个特性默认值为true [[writable]] 表示能否修改属性值.像前面例子中那样直接在对象上定义的属性,它们默认值为t

12-10面向对象--类与对象

二.类与对象 1.了解类:从这里开始,学习C#面向对象编程的基本内容,使用C#编程,所有的程序代码都放在类中,结构体是一个用户自定义的类型,是由其他类型组成的变量组,不存在独立于类之外的函数:因此,在面向对象中,类是面向对象编程的基本单元.类与类之间交互. 2.类的定义:一个类都可以包含2种成员:字段和方法. 1)类的字段一般代表类中被处理的数据(变量): 2)类的方法大多数代表对这些数据的处理过程或用于实现某种特定的功能,方法中的代码往往需要访问字段保存的数据. 简单的说,字段即变量,方法即函

面向对象与基于对象的区别

面向对象和基于对象的区别是多态,和继承无关. 基于对象仅仅支持了抽象数据类型的功能,继承也不过体现了一种is-a的关系,也是抽象数据类型,只是建立了一个层次体系.但是什么是面向对象呢?就是根 据对象的实际类型不同,可以自动完成不同的行为,而仅仅通过一致的调用形式.换句话说,也就是虚函数实现的多态.以上观点,在OO设计中已经得到了公认, 多态的另一种实现方法是泛型. “面向对象”和“基于对象”两个不同的概念.面向对象的三大特点(封装,继承,多态)却一不可,通常“基于对象”使用对象,但是无法利用现有

PHP中面相对象对象的知识点整理

面向对象 万物皆对象,将构成问题的事务分解到各个对象上,建立对象的目的不是为了完成一个工作,而是为了描述某个事务在解决问题中的行为,更符合人的思维习惯,代码重用性高,可扩展性. __________________________________________________________________ 类的概念 类 是一种抽象的概念,是具有相同语义定义对象的集合(具有相同属性和方法的集体),使用具体的类是不可行的,只能实例化.拿汽车举例,汽车的设计图纸就是类,汽车是对象.设计中重点是类的