基础面试题: 面向对象三大特性

C++或Java、C#等面向对象语言基础面试题

文章目录


前言

计算机语言的发展经历了机器语言、面向过程语言、以及面向对象语言,机器语言晦涩难懂高效,代表语言是汇编语言,面向过程语言代表C语言,面向对象语言代表C++和Java。由于在计算机发展早期,硬件设备极其有限,效率往往是第一要素,汇编语言语言以及后来的C语言就作为软件开发必修内容,但是随着硬件和计算机语言发展到今天,一个以对象管理为概念语言就孕育而生。

C++语言以及后来的Java语言就流行起来,面向对象语言的理解以正常社会个体来理解程序语言本身,符合人的正常思考思维和人性思维,同时对于大系统以及架构维护比先前的面向过程语言容易许多。

        在理解面向对象语言时,对于面向对象语言三大特性是什么就比较重要。


一、面向对象(OOP)三大特性

1)封装、继承、多态


二、封装

对象的属性(成员变量)和操作或服务(函数)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。类(class)就是封装的总体体现, public、protect、private成员属性的访问权限让开发者设定哪些细节可以暴露,哪些需要隐藏。    我们定义Person类,如下:

 class Person

{

        private int age;

        private string name;

        

        public void setAge(int age)

        {

                this.age = age;

        }

        public int getAge()

        {

           return age;

        }

        public void setName(string name)

        {

                this.name = name;

        }

        public string getName()

        {

                return name;

        }

}

对于 Person类有两个成员变量,age 和 name ,我们不需要直接对他进行访问,更改需要使用setAge接口,访问需要getAge(),这样保证数据的隐秘性成员变量不直接暴露。当然我们也可以定义 public int age,但是这不符合封装性的设计思想。

如何体现封装性:

       1)类(class)

                体现了封装性的完整性

       2)通过public,protect、private访问权限修饰

                它们控制想要访问的细节,哪些接口和成员变量需要被影藏,修改成员变量的接 

                口 setxxx()进行修改,getxxx()进行访问

       3)良好的接口设计

                应该只关注传入参数和返回值以及其作用,并不需要关注过多细节。


三、继承 

        一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类

class Base Character

{

        private int hp;

        private int mp;

        public void setHp(int hp)

        {

                this.hp = hp;

        }

        public int getHp()

        {        

                return hp;

        }

        public void setMp(int mp)

        {

                this.mp = mp;

        }

        public int getMp()

        {

              return mp;

        }

}

class Hero public BaseCharacter

{

        //当前任务ID

        private int currentTaskId;

        public void setCurrentTaskId(int id)

        {

                this.currentTaskId = id;

        }

        public int getCurrentTaskId()

        {

                return this.currentTaskId;

        }

        省略 ...

}

BaseCharater* p = new Hero();

hero类继承BaseCharacter类,hero和BaseCharacter都有hp和mp,这样hero就必重写,同时实现了代码设计的统一,可以通过统一接口i通过基类访问派生类,同时派生类有着基类所有属性。派生类是基类的扩展,基类的私有成员变量也会被派生类继承,只不过派生类不能访问罢了。

继承让代码更简洁,但是继承往往打破的封装性,程序设计往往追求高内聚、低耦合,继承是一种高耦合的设计,所以在代码设计时需要做出取舍。


四、多态

多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

多态体现:

 多态最直接的体现virtual 虚函数和纯虚函数

如下有:战斗角色类FightCharacter,它的子类都有attack攻击行为,但是attack攻击行为做执行的细节有很大的不同。我们定义为纯虚函数

同时有每帧更新行为,子类可能与父类的更新内容一样,也可能不一样,所以我们把他定义为虚函数,

class FightCharacter public BaseCharacter

{

        //攻击行为

        public  virtual void  attack(int destId)=0;

        public virtual void update()

        {

                省略 ...

        }

}

class Hero public FightCharacter

{

          省略 ...

        //英雄攻击时有自己的逻辑

        public override void attack(int destId)

        {

                 省略 ...

        }

        public override  void update()

        {

                省略 ...

        }

        省略 ...

}

class Monster public FightCharacter

{

          省略 ...

        //怪物攻击时有自己的逻辑

        public override void attack(int destId)

        {

                 省略 ...

        }

        public override  void update()

        {

                省略 ...

        }

        省略 ...

}

FightCharacter* pHero = new Hero();

FightCharacter* pMonster = new Monster ();

pHero->attack(); //调用的是pHero实际指向对象所定义的类的attack函数

pHero->update();//调用的是pHero实际指向对象所定义的类的update函数

pMonster->attack();//调用的是pMonster实际指向对象所定义的类的attack函数

pMonster->update();//调用的是pMonster实际指向对象所定义的类的update函数

在什么时候定义虚函数,在什么时候定义纯虚函数 

如果子类都有某一行为,但是各个子类行为实现细节没有统一性,那么就定义纯虚函数

如果子类中都有某一行为,但是各个子类有些许差异,这时候应该定义为虚函数。


总结

面向对象的三大特性:封装、继承、多态

封装的体现:类和public、protect、private 访问权限,良好的接口设计

继承:通过派生子类,来复用父类的属性和成员,提高代码的复用率与代码简洁、易维护,继承是高耦合设计,打破封装性,要有选择性使用,把握分寸。

多态的体现:虚函数与纯虚函数

猜你喜欢

转载自blog.csdn.net/lejian/article/details/128865702
今日推荐