面向对象三大特征

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/21795563

      最近刚开始学习设计模式,在学习初期,把面向对象这个概念弄明白是很有必要的。

       之前接触过C语言的基础,后来又学了一点VB,不过这都不是面向对象的语言,当然在编程中也就无法体会到面向对象的思想。

       最近接触了软件工程、UML之后才渐渐了解了面向对象的概念,继而又简单学习了一下C++、C#,下面以C#为工具来总结一下目前所认识的面向对象。

         何为对象?

    进入正题之前,我们先来探讨一下什么是“对象”,不要误会,此“对象”非彼“对象”→_→。

    举个例子,一只小狗,它有眼睛、嘴巴、鼻子、颜色等静态特征(属性),也有吃东西、睡觉等动态特征(方法);又比如一个手机,它既有型号、大小等静态特征(属性),也有打电话、发短息等动态特征(方法)。所以,对对象简单的定义就是“对象是一个包含属性和方法的整体”。

    面向对象编程(OOP)

      早期的计算机编程是基于面向过程的方法,例如实现一个求圆的面积的功能:S=3.14*r*r,通过设计一个算法就可以解决问题。随着需求的不断提高,需要被解决的问题也变得越来越复杂,例如前段时间比较火的“捕鱼”游戏,在游戏中,有成千上万条鱼、无数子弹,还有渔网、海底装饰物等等,但在制作游戏的过程中,我们的编程人员不能根据每条鱼的外形,游动方式而写一段相应的代码吧,那还不累死……所以用面向过程的方法来解决就有些困难了,这时就要用到面向对象。

    一切事物皆对象,我们可以将现实世界中的任何事物看成是对象,比如在“捕鱼”游戏的实现中,每条鱼就是一个对象,每张网是一个对象……但是为了避免枯燥乏味,不能只要一条鱼,一张网吧,所以,就要把所有的鱼的共同点找出来,抽象出一个“鱼类”,把所有网的共同点找出来,抽象出一个“网类”……然后用的时候就可以让个鱼类实例化出无数条鱼。所以说,面向对象解决了传统的面向过程的编程方法所无法解决的代码复用的问题。

   面向对象的特征

面向对象有三大特征:封装、继承和多态。

封装

       封装就是把客观的事物抽象成类,并且类把自己不想对外开放的成员“藏起来”,仅仅提供一些相应的接口供外界访问,实现了信息隐藏,提高了安全性。如一个钟表类,有时、分、秒等属性,有调整时间等方法,实现封装的代码为:

 class Clock
    {
        private int hour, minute, second;
        public int Hour
        {
            get { return Hour; }
            set { Hour = value; }
        }
        public int Minute
        {
            get { return Minute; }
            set { Minute = value; }
        }
        public int Second
        {
            get { return Second; }
            set { Second = value; }
        }
    }

       在代码中,hour、minute、second就是Clock类“藏起来”的属性,Hour、Minute和Second就相当于是外界访问Clock这些私有属性的接口。

继承

        假如在整个捕鱼游戏中,有成千上万条鱼,虽然有许多种类的鱼,但这些鱼会有许多共同点,比如每条鱼在屏幕上都会有一个位置(x坐标和y坐标),都会向前游动等等,这时候就可以根据所有鱼的共同特征,抽象出来一个“鱼”类,这个“鱼”类中包含了所有鱼的共同点,因此在实例化每种鱼的时候都使得公用代码得到了共享,避免了重复。

class Fish
    {
        protected double x;
        protected double y;
        public Fish()
        {
            x = 0;
            y = 0;
        }
        public double X
        {
            get { return x; }
            set { x = value; }
        }
        public double Y
        {
            get { return y; }
            set { y = value; }
        }
        public void Swim(double distance_x, double distance_y)
        {
            x += distance_x;
            y += distance_y;
        }
    }
    class Turtle : Fish
    {
        public Turtle() : base() { }
        public void Turn()
        {
            //为了区别于其他的鱼,就给乌龟加一个转头并按原路返回的方法
            //……相关代码……
            //……………………
            //……………………
            //……相关代码……
        }
    }
    class Mermaid : Fish
    {
        public Mermaid() : base() { }
        public void SwingArms()
        {
            //为了区别于其他的鱼,就给美人鱼加一个摇摆双臂的方法
            //……相关代码……
            //……………………
            //……………………
            //……相关代码……
        }
    }

这时,Fish类就是父类(基类),Turtle类和Mermaid类就是子类(派生类)。

多态

       多态就是用不同的对象调用调用相同的方法,执行不同的操作。还是用捕鱼游戏来举例子,假定美人鱼只能一直向前游,而乌龟可以向任意方向(游动的时候x坐标和y坐标都可以发生改变),则每种鱼就不能只是单单继承Fish的Swim方法了,应该让特定的鱼种继承了Swim方法之后能够有不同游法(虽然同样是游泳,但各有各游的方式,就如同小猫叫的时候是“喵”,小狗叫的时候是“汪”)。

       实现方法便是在父类中

class Fish
    {
        protected double x;
        protected double y;
        public Fish()
        {
            x = 0;
            y = 0;
        }
        public double X
        {
            get { return x; }
            set { x = value; }
        }
        public double Y
        {
            get { return y; }
            set { y = value; }
        }
        public virtual void Swim(double distance_x, double distance_y)
        {
        }
    }
    class Turtle : Fish
    {
        public Turtle() : base() { }
        public void Turn()
        {
            //为了区别于其他的鱼,就给乌龟加一个转头并按原路返回的方法
            //……相关代码……
            //……………………
            //……………………
            //……相关代码……
        }
        public override void Swim(double distance_x, double distance_y)
        {
            x += distance_x;
            y += distance_y;
        }
    }
    class Mermaid : Fish
    {
        public Mermaid() : base() { }
        public void SwingArms()
        {
            //为了区别于其他的鱼,就给美人鱼加一个摇摆双臂的方法
            //……相关代码……
            //……………………
            //……………………
            //……相关代码……
        }
        public override void Swim(double distance_x, double distance_y)
        {   
            //美人鱼游的时候只是x坐标发生改变
            x += distance_x;
        }
    }

代码中,在Fish类中的Swim方法要变为虚方法(其函数体内可以为空),子类继承这个虚方法后进行重写(即根据自己的特点进行扩充或改变)。如果父类中的虚方法有形参,则子类中重写的时候,函数的形参列表要与父类中虚方法的形参列表一致。

如有不足与纰漏,恳请您留下宝贵意见与建议,感激不尽!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端技术探索

常见算法面试题

这几天在网上看到一篇关于算法面试题的博客,归纳的很好,有不少经典的题目,大部分来自《编程珠玑》、《编程之美》、《代码之美》三本书。这里给出书上的解答以及一些思考...

2812
来自专栏编舟记

函数式编程简介

1900年,Hilbert 提出了数学界悬而未决的10大问题,后续陆续添加成了23个问题,被称为著名的 Hilbert 23 Problem。针对其中第2个决定...

1984
来自专栏追不上乌龟的兔子

[多少懂点位运算]找出唯一的数字

大家都知道现代计算机的底层是以二进制为基础的,计算机所有的操作最后都归结到了简单的二进制位运算上:与,或,非和异或。

2555
来自专栏专注数据中心高性能网络技术研发

[LeetCode]HashTable主题系列{第3题}

1. 内容介绍 开一篇文章记录在leetcode中HashTable主题下面的题目和自己的思考以及优化过程,具体内容层次按照{题目,分析,初解,初解结果,优化解...

3419
来自专栏大数据文摘

正则表达式太慢?这里有一个提速100倍的方案(附代码)

2354
来自专栏chenjx85的技术专栏

leetcode-169-Majority Element

2114
来自专栏移动端开发

快速排序OC、Swift版源码

前言: 你要问我学学算法在工作当中有什么用,说实话,当达不到那个地步的时候,可能我们不能直接的感觉到它的用处!你就抱着这样一个心态,当一些APP中涉及到算法...

2208
来自专栏ACM小冰成长之路

51Nod-1645-中位数变换

ACM模版 描述 ? 题解 这个题很明显是找规律的问题,直接暴力肯定会超时……虽然我也是暴力也两发才反应过来……平时做题总是抱着侥幸心理,比赛时却总是胆小如鼠…...

2117
来自专栏Crossin的编程教室

【每周一坑】特殊回文数

Thank God It’s Friday! again! 又到了惬意的周末了,祝大家周末愉快,闲暇之余记得练习编程技能啊!另外,上海的朋友可以安心在家写代码了...

3507
来自专栏chenjx85的技术专栏

leetcode-258-Add Digits

2134

扫码关注云+社区

领取腾讯云代金券