目录

前言

为什么要封装?

为什么要继承?

什么是多态?


前言

计算机科学是一门实践性很强的科目,所有理论都不是凭空而来的,某种理论的出现都是为了解决过往的不足。面向对象是其中之一,但我们不能单从字面去理解面向对象这个新名词,而是通过实践,从面向过程自然过渡到面向对象中来。

本文假设有一个宠物模拟系统,每个宠物都是一个相对独立的子系统,因为它们有着各自的特性,为了模拟现实中的宠物,在逻辑上每个宠物也应该当成独立的个体来编写代码,这样有助于人类的理解。

注:

文中的代码主要是一些说明问题的伪代码,如果想运行起来,需要读者自行发挥想象力,补充完善。

另外,C语言在命令行下边会有中文乱码问题,尽量使用Visual studio来写程序,可以省去很多麻烦。

为什么要封装?

封装是为了将某些相关联的数据和操作进行隔离,放在一个独立的容器里。在编程语言中,这个窗口叫啊类,将类加载到内存,初始后变成一个独立可访问的数据块,这个数据块就成了一个对象。

在本文的示例中,类相当于对各种宠物的文字描述,对象(或实例)是一个个实际的宠物个体。

我们先用不面对对象的C来设计一个宠物模拟程序,先不看实现,只看定义。假设家里刚开始只有一只哈士奇,为了模拟狗狗的日常,我们在头文件里如此定义:

/*狗狗*/
#pragma once#include <stdio.h>
typedef struct
{wchar_t* name;//名字int age;//年龄char gender;//性别int color;//颜色int hp;//健康值int fp;//怒值,达到一定程度会咬人int exps;//友好值,低到一定程序会离家出走
}Pet;/*
* 呼唤宠物
*/
void call();/*
* 抚摸宠物
*/
void touch();
/*打狗*/
void beat();
/*会叫*/
void bark();/*会咬人*/
void bite();
/*离家出走,消失不见*/
void hide();
/*溜狗*/
void walk();

后来又抱了只猫,猫跟狗狗一样都是用来撸的,只是猫不用溜,但要准备猫沙,还会抓老鼠,要给它铲屎,本来猫的头文件应该定义成这样:

/*猫咪*/
#pragma once#include <stdio.h>
typedef struct
{wchar_t* name;//名字int age;//年龄char gender;//性别int color;//颜色int hp;//健康值int fp;//怒值,达到一定程度会咬人int exps;//友好值,低到一定程序会离家出走
}Pet;/*
* 呼唤宠物
*/
void call();/*
* 抚摸宠物
*/
void touch();
/*打猫*/
void beat();
/*会叫*/
void bark();/*会咬人*/
void bite();
/*离家出走,消失不见*/
void hide();
/*铲屎*/
void clean();
/*抓老鼠*/
void catchmouse();

但这样一来,编译器会重复定义的错误,所以改方法名,以示区别,可以每个方法前添加前缀来实现,变成这样:

/*猫咪*/
#pragma once#include <stdio.h>
typedef struct
{wchar_t* name;//名字int age;//年龄char gender;//性别int color;//颜色int hp;//健康值int fp;//怒值,达到一定程度会咬人int exps;//友好值,低到一定程序会离家出走
}Pet;/*
* 呼唤宠物
*/
void catcall();/*
* 抚摸宠物
*/
void cattouch();
/*打猫*/
void catbeat();
/*会叫*/
void catbark();/*会咬人*/
void catbite();
/*离家出走,消失不见*/
void cathide();
/*铲屎*/
void catclean();
/*抓老鼠*/
void catcatchmouse();

看上去好像解决问题了,但指不定哪天又养只鹦鹉,养了条黄金莽什么的,那就不断往上加吧,如果没有重样的宠物还好,但遇到重样的又麻烦了,比如狗狗生了小狗,鹦鹉生了蛋等等,虽然技术上是可以解决的,比如每个狗狗函数加上参数,以标明是哪只狗,但这样会变得非常的混乱,修改量也不是一般的大。

我们再用Java实现一遍看看,先写个Dog类:


public class Dog {String name;//名字int age;//年龄char gender;//性别int color;//颜色int hp;//健康值int fp;//怒值,达到一定程度会咬人int exps;//友好值,低到一定程序会离家出走public void call(){exps += 100;System.out.println(String.format("%s,过来!", name));System.out.println("汪汪汪");System.out.println(String.format("好感度值增加100!当前好感度:%d", exps));}public void touch(){exps += 200;System.out.println(String.format("摸一摸%s!\n", name));System.out.println("汪汪!");System.out.println(String.format("好感度值增加200!当前好感度:%d\n", exps));}public void beat(){}public void bark(){}public void bite(){}public void hide(){}public void walk(){}}

然后复制一份,改个类名,修改少部分内容基本就OK了:


public class Cat {String name;//名字int age;//年龄char gender;//性别int color;//颜色int hp;//健康值int fp;//怒值,达到一定程度会咬人int exps;//友好值,低到一定程序会离家出走public void call(){exps += 100;System.out.println(String.format("%s,过来!", name));System.out.println("喵喵喵");System.out.println(String.format("好感度值增加100!当前好感度:%d", exps));}public void touch(){exps += 200;System.out.println(String.format("摸一摸%s!\n", name));System.out.println("喵喵!");System.out.println(String.format("好感度值增加200!当前好感度:%d\n", exps));}public void beat(){}public void bark(){}public void bite(){}public void hide(){}void catclean(){}void catcatchmouse(){}
}

为什么要继承?

虽然CTRL+V、CTRL+C很爽,但如果有一天,想换个姿势撸宠物,比如要小动物都要亲亲或者抱抱,如果宠物少的情况下,每个宠物类里加两个方法倒也不是难事,但万一家里小可爱们太多了,有十几上百个,那改起来是要命的,那能不像动物学那样,可以将宠物按某种分类,层层向下扩展。答案是可以的。

不管是猫是狗还是鹦鹉,它们都有个共同称呼,叫宠物,OK,我们可以定义一个宠物的类Pet:


public class Pet {protected String name;// 宠物都有名字protected int age;// 宠物都有寿命protected char gender;// 宠物都分雌雄protected int color;// 宠物都有颜色protected int hp;// 宠物都要追踪健康情况protected int fp;// 宠物都在某些情况都会生气,达到一定程度会咬人protected int exps;// 宠物都跟主人都有亲密程度,低到一定程序会离家出走/*** 宠物都能被呼唤*/public void call() {exps += 100;System.out.println(String.format("%s,过来!", name));System.out.println(String.format("好感度值增加100!当前好感度:%d", exps));}/*** 宠物都可以摸*/public void touch() {exps += 200;System.out.println(String.format("摸一摸%s!\n", name));System.out.println(String.format("好感度值增加200!当前好感度:%d\n", exps));}
}

然后再修改具体宠物的类比如狗:

/*** 狗狗**/
public class Dog extends Pet {/*** 狗会叫*/public  void bark(){System.out.println("汪汪!");}}

再改下猫:

/*** 猫猫**/
public class Cat extends Pet {/*** 猫会妙妙*/public void Miaow() {System.out.println("喵喵");}
}

接着,我们给宠物们都增加亲亲抱抱的功能,只要修改Pet这个类就行了:

/*** 小可爱们**/
public class Pet {protected String name;// 宠物都有名字protected int age;// 宠物都有寿命protected char gender;// 宠物都分雌雄protected int color;// 宠物都有颜色protected int hp;// 宠物都要追踪健康情况protected int fp;// 宠物都在某些情况都会生气,达到一定程度会咬人protected int exps;// 宠物都跟主人都有亲密程度,低到一定程序会离家出走/*** 宠物都能被呼唤*/public void call() {exps += 100;System.out.println(String.format("%s,过来!", name));System.out.println(String.format("好感度值增加100!当前好感度:%d", exps));}/*** 宠物都可以摸*/public void touch() {exps += 200;System.out.println(String.format("摸一摸%s!\n", name));System.out.println(String.format("好感度值增加200!当前好感度:%d\n", exps));}/*** 亲亲*/public void kiss() {exps += 200;System.out.println("啾啾");}/*** 亲亲*/public void embrace() {exps += 200;System.out.println("抱抱");}
}

什么是多态?

不同的宠物,虽然在主人眼中是一样的,但撸完会有不同的反应,这些行为是动物自己做出来的,只有具体到每个宠物本身,主人才能体验到各个宠物的反应。但抽象点说,宠物是用来撸的,主人可能并不在意宠物的具体反应,而是享受这个互动的过程。所以多态就是抽象层面的一致,而具体层面的不一致。

比如狗狗:

/*** 狗狗**/
public class Dog extends Pet {@Overridepublic void touch() {super.touch();//摸玩狗狗,它会冲着你叫bark();}/*** 狗会叫*/public void bark(){System.out.println("汪汪!");}}

比如猫:

/*** 猫猫**/
public class Cat extends Pet {@Overridepublic void touch() {super.touch();//猫会打呼噜System.out.println("呼噜噜~");}/*** 猫会妙妙*/public void Miaow() {System.out.println("喵喵");}
}

比如鹦鹉:

/*** 鹦鹉**/
public class Parrot extends Pet {@Overridepublic void touch() {exps -= 50;// 鹦鹉直接开口骂娘System.out.println("烦死了~");}}

以上示例中,每个宠物都有touch()的功能,也就是被撸这一点是一致的。主人对待宠物时,在这点上一致的。但同时宠物可能在被撸后,表现出所有宠物共同的反应,也可能是自己独特的反应。比如猫狗都调用了super.touch(),说明猫狗被撸时会表现出一些共同的特性。而鹦鹉则完全特立独行,还降低了好感度。

面向对象的个人理解(封装/继承/多态实践)相关推荐

  1. python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)

    面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...

  2. Day55-每日一道Java面试题-Java 面向对象编程三大特性: 封装 继承 多态

    Java 面向对象编程三大特性: 封装 继承 多态 封装 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问.但是如果一个类没有 ...

  3. 小白理解——封装继承多态

                                      一.封装 是什么:首先是抽象,把事物抽象成一个类,其次才是封装.对外表示为一个对象,隐藏对象的属性和动作实现的细节,仅对外公开接口. ...

  4. 面向对象 编程及面向对象三大属性:封装 继承 多态

    面向对象 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构.应用平台.分布式系统.网络管理结构. ...

  5. Python学习笔记④——类、面向对象的三大特征 [封装+继承+多态]

    ✅ Blogger Learns Python is for learning the "Deep Learning". 文章目录 一.面向对象编程的简介 二.类与对象 -- 基础 ...

  6. 面向对象的四大特征 封装 继承 多态 抽象

    1.封装 广义: 类 方法 包 的定义本身就是一种封装 狭义: 在设计一个类的时候 将所有的属性设置为私有的 并对各个私有的属性设计相应的 存/取方法 来完成对属性的使用 私有化只能代表封装的特性 可 ...

  7. OC面向对象的三大特征(封装 继承 多态)习题2 复合

    复合:一个类中有一个成员变量是另外一个类的对象. 比如我现在要制作一台电脑,电脑需要CPU,显示器,鼠标和键盘等.这些东西的研发都是很复杂的过程.如果现在有成型的CPU等组件,就可以直接用这些组件攒一 ...

  8. python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态

    六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...

  9. 大数据笔记8—java基础篇4(面向对象-封装-继承-多态)

    面向对象 一.面向对象 1.面向过程 1.2.举例 1.3.总结 二.面向对象 1.简述 2.举例 3.思想特点 2.1.类的定义格式 2.1.1.简述 2.2.2.格式 2.3.3.示例 三.类的使 ...

最新文章

  1. 神经网络学习到的是什么?(Python)
  2. 2ex1逆向寒假生涯(24/100)
  3. ANTLR和网络:一个简单的例子
  4. 数据结构一—— 数组
  5. 【文章】一副对联,便写尽了人生
  6. 笔记10:时时屏幕抓取小程序
  7. Spring Session Management – Spring Session JDBC
  8. phpstom怎样导出数据库_详解mysql数据库sql优化技巧总结
  9. 区块链的概念是由()于2008年提出_区块链,下一个时代的基础设施
  10. Excel 2007数据透视表如何对数值进行筛选
  11. Zune vs iPod
  12. “System.ComponentModel.Win32Exception配额不足,无法处理此命令。”问题
  13. 【有奖调研】| 参与区块链调研,赢千元大奖!
  14. 将 libVLC 视频渲染到 QWidget 中
  15. Resultful接口实现后端文件下载
  16. 神牛TT685C闪光灯ETTL模式不同步解决方案
  17. 检查nmos管是否损坏
  18. 腾讯实时音视频SDK[一]:业务和场景
  19. 浏览器提示ssl证书过期怎么办
  20. AI创意赛火热,赛事能成BAT强化AI优势的新动能?

热门文章

  1. 精心收藏风林火山系统下载
  2. 前端开发入门教程-HTML标签(上)
  3. stc 51接口功能
  4. 智能验证码助力银行数字化营销
  5. 现场直击 | 沈阳新技术交流会,实景三维再“出圈”
  6. buuctf 梅花香之苦寒来
  7. Qt下libusb-win32的使用(转)
  8. 一元二次函数的万能公式
  9. 13视频监控-02视频监控画面-videopanel
  10. 【CEOI2015 Day2】世界冰球锦标赛( 提高+/省选-) 题解