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

目录

前言

为什么要封装?

 为什么要继承?

什么是多态?


前言

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

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

注:

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

另外,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 {

	@Override
	public void touch() {
		super.touch();
		//摸玩狗狗,它会冲着你叫
		bark();
	}

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


}

比如猫:

/**
 * 猫猫
 *
 */
public class Cat extends Pet {

	@Override
	public void touch() {
		super.touch();
		//猫会打呼噜
		System.out.println("呼噜噜~");
	}

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

比如鹦鹉:

/**
 * 鹦鹉
 *
 */
public class Parrot extends Pet {

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

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值