面向对象的概念详解(转)

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

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

1.对象是什么?

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

2.对象有什么?

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

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

代码示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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 { getset; }

    public string Brand { getset; }

    public string Model { getset; }

    public string Color { getset; }

}

    public static void Main(string[] args)

    {

        var car = new Car("张三""宝马""B01""黑色");//这是一个对象

        car.Color = "红色";//状态被改变

        car.Owner = "李四";//状态被改变

    }

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

代码示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

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 { getset; }

    public string Brand { getset; }

    public string Model { getset; }

    public string Color { getset; }

    public string Status { getprivate set; }

    public Driver Driver { getset; }

    public void Start() //启动方法,被动

    {

        if (this.Driver!=null)

        {

            this.Status = "运行中";

        }

        else

        {

            throw new InvalidOperationException("没有驾驶员,不能自动启动!");

        }

    }

    public void Stop() //启动方法,被动

    {

        this.Status = "停止";

    }

}

public class Driver

{

    public string Name { getset; }

    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.对象角色定位

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

public class Person //人

{

    public string IdNo{get;set;}

    public string Name { getset; }

    public string Sex { getset; }

    public double Height { getset; }

    public double Weight { getset; }

    public DateTime BirthDay { getset; }

}

public class Post //文章

{

    public string Title { getset; }

    public string Content { getset; }

    public Author Author { getset; }

    

    public DateTime CreateDatetime { getset; }

}

public class Author : Person //角色为作者

{

    public void Write(Post post)

    {

        //行为

    }

}

public class Book //书

{

    public string Name { getset; }

    public DateTime IssuedDate { getset; }

    public List<Post> Posts;

}

public class Library //图书馆

{

    public string Name { getset; }

    public List<Book> Books { getset; }

    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 { getset; }

    public IEnumerable<Post> Read(Book book,params int[] pages) //读书,主动

    {

        var posts = new List<Post>();

        if (pages != null)

        {

            foreach(int 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 { getset; }

    public string Status{get;private set;}

    public void Start()

    {

        this.Status="运行中";

    }

    public void Stop()

    {

        this.Status="停止";

    }

}

结 尾

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

时间: 2024-10-17 08:57:52

面向对象的概念详解(转)的相关文章

LINUX 信号概念详解

LINUX 信号概念详解 我们运行如下命令,可看到Linux支持的信号列表: # kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP

Linux 程序设计学习笔记----终端及串口编程基础之概念详解

转载请注明出处,谢谢! linux下的终端及串口的相关概念有: tty,控制台,虚拟终端,串口,console(控制台终端)详解 部分内容整理于网络. 终端/控制台 终端和控制台都不是个人电脑的概念,而是多人共用的小型中型大型计算机上的概念. 1.终端 一台主机,连很多终端,终端为主机提供了人机接口,每个人都通过终端使用主机的资源. 终端有字符哑终端和图形终端两种. 控制台是另一种人机接口, 不通过终端与主机相连, 而是通过显示卡-显示器和键盘接口分别与主机相连, 这是人控制主机的第一人机接口.

varnish基础概念详解

varnish基础概念详解 比起squid更加轻量级,大致有以下几个特点: ·可以基于内存缓存,也可以在磁盘上缓存,但是就算存放在磁盘上,也不能实现持久缓存 只要进程崩溃,此前缓存统统失效,无论是在内存还是在磁盘,但是现在已经具备持久缓存功能,但是仍然在实验阶段,经常容易崩溃,而且最大大小不能超过1G 如果期望内存大小超过几十个G,比如图片服务器,纯粹使用内存,性能未必好,这时候可以使用磁盘进行缓存,或SSD X 2 做RAID 避免磁盘损坏,在实现随机访问上 ssd硬盘要比机械硬盘要好的多,如

RAID0 RAID1 RAID3 RAID5 RAID6 RAID10 RAID50概念详解

RAID0 RAID1 RAID3 RAID5 RAID6 RAID10 RAID50概念详解摘要:RAID 0又称为Stripe或Striping(条带卷),它代表了所有RAID级别中最高的存储性能.RAID 0提高存储性能的原理是把连续的数据分散到多个磁盘上存取,这样,系统有数据请求就可以被多个磁盘并行的执行,每个磁盘执行属于它自己的那部分数据请求.这种数据上的并行操作可以充分利用总线的带宽,显著提高磁盘整体存取性能RAID 1又称为Mirror或Mirroring(镜像卷),它的宗旨是最大

SOA概念详解

1.概述 1.1基本定义 SOA(Service-Oriented Architecture)既面向服务的体系结构,是一个组件模型,它将应用程序员的不同功能但是(称为服务)通过定义良好的接口联系起来.SOA建立在Web服务的基础上,它可以看做是B/S模型.XML/Web Service技术之后的自然延伸.SOA将能够帮助我们站在一个新的告诉理解企业级架构中的各种组件的开发.部署形式,它将帮助企业系统架构这以更迅速.更可靠.更具有重用性的性能架构整个业务系统.较之以往,以SOA架构的系统能够更加从

进行概念详解 多线程上篇(二)

操作系统是程序与硬件交互的中间层,现代操作系统将程序的一次执行抽象为进程和线程的概念. 进程作为资源分配的基本单位,线程作为执行的基本单位. 进程和线程其实就是操作系统程序本身实现控制一个程序运行的数据项描述 所有的程序都是面向语言进行开发的,而语言本身是面向操作系统的,线程是操作系统对程序一次运行的抽象 所以,所有的多线程编程模型,必然遵从操作系统的大逻辑,必然是符合操作系统的对线程的抽象概念,操作系统在抽象之上提供了API供应用程序调用 简言之,应用程序的底层是借助于操作系统来完成多线程编程

对于面向对象的部分详解

面向对象部分详解如下: 一.面向对象 什么是面向对象? 面向对象与面向过程相比: 面向过程:其核心就是过程,过程指的是解决问题的步骤,如先干什么再干什么就好像是一条流水线:该思维方式编程被称为机械式的编程思维. 面向过程的优点:复杂的问题流程化进而流程化 面向过程的缺点:扩展性差(改一个地方其他的地方也必须更改) 面向对象:其核心就是对象,对象指的是特征与功能的结合体,在Python3中世间万物都是对象或在上帝眼里世间万物都是对象即使没有的对象也可以创造出来,这种思维方式被称为上帝式的编程思维.

http与www服务基础概念详解

dns解析过程: dns cache command:ipconfig /displaydns   -->显示DNS CACHE内容ipconfig /flushdns     -->清除DNS CACHE windows hosts路径:C:\Windows\System32\drivers\etc\hosts http协议简介:HTTP协议,全称HyperText Transfer Protocol,中文名称超文本传输协议,是互联网上应用最为广泛的一种网络协议.所有的www都必须遵守这个标

Android屏幕密度(Density)和分辨率概念详解

移动设备有大有小,那么如何适应不同屏幕呢,这给我们编程人员造成了很多困惑.我也是突然想到这些问题,然后去网上搜搜相关东西,整理如下. 首先,对下面这些长度单位必须了解. Android中的长度单位详解(dp.sp.px.in.pt.mm) 看到有很多网友不太理解dp.sp和px的区别:现在这里介绍一下dp和sp.dp也就是dip.这个和sp基本类似.如果设置表示长度.高度等属性时可以使用dp 或sp.但如果设置字体,需要使用sp.dp是与密度无关,sp除了与密度无关外,还与scale无关.如果屏