自学C++之类的继承
来源:互联网 发布:淘宝网客服怎么联系 编辑:程序博客网 时间:2024/05/06 00:19
继承是一种编程技术,可以从现有类中构造一个新类,通过新类实现面向对象的程序设计。
类的继承的分类:1、单继承 2、多继承 3、虚继承
一、下面我们先来了解一下单继承;
程序员能够根据已有类派生一个新类,这个新类继承了父类所有公有和受保护的数据成员和方法。
那么,什么是类的继承呢?
类的继承--是指派生出来的类可以全部或者部分继承父类,同时,派生类还可以加入自己所需要的新特征和功能。简单的说,就是,派生类可以有选择性的继承父类的某些数据成员或者方法,同时,定义属于自己不属于父类的一些新的数据成员或者方法。
新的类继承了原有类的特性,被称为原有类的派生类或者子类。而原有类被称为新类的基类或者父类。
单继承----就是以一个基类派生新类。
派生一个新类的格式:
class 类名称 : 访问限定符(public 、protected、private) 基类名称
例如: class CDog : [public / protected / private] CAnimal {...........}
在C++中有三种访问限定符
1、访问限定符 public :表示,如果在父类中的public类型 的数据成员和方法,那么在子类中仍然是public 类型的。如果在父类中的protected类型的数据成员和方法,那么在子类中也是protected类型的数据成员和方法。
2、访问限定符 protected :表示,如果在父类中的public 、protected类型的数据成员和方法,那么在子类中全部都变成了protected类型的数据成员和方法。
3、访问限定符private :表示:如果在父类中的public 、protected 类型的数据成员和方法,那么在子类中全部都变成private类型的数据成员和方法。
#include "stdafx.h"
#include "string.h"
class CAnimal{
//声明成员变量
protected :
char* m_name ; //名称
char* m_color ; //颜色
//定义4个方法,来获取和设置成员变量
public:
char* GetName() ;
char* GetColor() ;
void SetName(char* name) ;
void SetColor(char* color) ;
void Move() ;
CAnimal() ;
~CAnimal() ;
} ;
char* CAnimal::GetName(){
return m_name ;
}
char* CAnimal::GetColor(){
return m_color ;
}
void CAnimal::SetName(char* name){
strcpy(m_name,name) ;
}
void CAnimal::SetColor(char* color){
strcpy(m_color,color) ;
}
CAnimal::CAnimal(){
m_name = new char[5] ;
m_color = new char[5] ;
}
CAnimal::~CAnimal(){
delete []m_name ;
delete []m_color ;
}
void CAnimal::Move(){
printf("Animal is moving \n") ;
}
//现在定义一个CDog类,该类继承了基类CAnimal类,这样,CDog类就有了CAnimal类中所有非私有的数据成员和方法
class CDog : public CAnimal{
protected :
char* m_kind ;
public :
char* GetKind() ;
void SetKind(char* kind) ;
void yelp();
CDog() ;
~CDog() ;
};
void CDog::yelp(){
printf("Dog can yelp") ;
}
CDog::CDog(){
m_kind = new char[10] ;
}
void CDog::SetKind(char* kind){
strcpy(m_kind , kind) ;
}
char* CDog:: GetKind(){
return m_kind ;
}
CDog::~CDog(){
delete []m_kind ;
}
//主函数
int main(int argc, char* argv[])
{
//实例化子类对象
CDog dog ;
dog.SetColor("白色") ;
dog.SetName("狗") ;
//调用父类的方法
dog.Move() ;
//调用自己的方法
dog.yelp() ;
printf("\n") ;
return 0;
}
上面学习了单继承,了解了什么是单继承,现在来看一下,什么是多继承。
二、多继承
定义:多继承是指子类继承了多个父类。
语法:class 子类名称 : 访问限定符1 父类名称1 , 访问限定符2 父类名称2 , ........
例如:class CWaterBird : public CBrid ,protected CFish {} ;
#include "stdafx.h"
class CBird{
public :
void fly() ;
void move() ;
} ;
class CFish{
public:
void swim() ;
void move() ;
} ;
//实例化方法
void CBird::fly(){
printf("I can fly \n") ;
}
void CBird::move(){
printf("bird can move \n") ;
}
void CFish::swim(){
printf("I can swim \n") ;
}
void CFish::move(){
printf("fish can move \n") ;
}
//CWaterBird继承CBrid和CFish类
class CWaterBird : public CBird ,public CFish {
public :
void run() ;
};
void CWaterBird ::run(){
printf("waterBird can run \n") ;
}
int main(int argc ,char* argv[]){
//实例化子类对象
CWaterBird waterBird ;
//调用父类CBird中的fly方法
waterBird.fly();
//调用父类CFish中的swim方法
waterBird.swim() ;
printf("\n") ;
return 0 ;
}
注意:采用多继承会出现很多的问题。
比如上面的类CBird和类CFish中都有move()方法。那么如果子类调用move方法,是调用哪个父类中的move方法呢?
waterBird.move(); //如果你是直接写这句,那么程序会报错。
【'CWaterBird::move' is ambiguous ,could be the 'move' in base 'CBird' of class 'CWaterBird',or the 'move' in base 'CFish' of class 'CWaterBird'】
这时,你就必须指明具体的调用哪个父类的方法
waterBird.CBird::move() ;
waterBird.CFish::move() ;
还有一个问题就是:如果CBird和CFish类派生于同一个基类CAnimal,那么CWaterBird中就会有两个CAnimal对象,如果CWaterBird没有覆盖CAnimal类中的方法,如何调用CAnimal中的方法呢?
如果你直接调用CAnimal中的方法,那么编译器会直接报错。
【'CWaterBird::breath' is ambiguous,could be the 'breath' in base 'CAnimal' of base 'CBird' of class 'CWaterBird',or the 'breath' in base 'CAnimal' of base 'CFish' of class 'CWaterBird'】
编译器不知道调用的是CBird父类的方法还是CFish父类中的方法。那么怎么解决这个问题呢?和上面的类似,你需要指定类名称即可。
waterBird.CBird::breath() ;
貌似上面的方法有些麻烦,是吧。那么在C++中是否能够使CWaterBird类对象中只存在一个CAnimal对象呢?这样就可以直接调用CAnimal中的方法了。答案是有的。
三、虚继承
在C++中可以采用虚继承的方式来实现。用virtual关键字进行的继承叫做虚继承,当进行虚继承时,编译器会通过指针对其进行处理,使其只能产生一个基类子对象,这样的话,编译器就不会报错了。
语法:
class 子类名称 : virtual 访问限定符 基类名称
例如:class CBird : virtual public CAnimal
class CAnimal{
public :
void breath() ;
};
void CAnimal::breath(){
printf("animal can breath \n") ;
}
class CBird : virtual public CAnimal{
public :
void fly() ;
void move() ;
} ;
class CFish : virtual public CAnimal{
public:
void swim() ;
void move() ;
} ;
//实例化方法
void CBird::fly(){
printf("I can fly \n") ;
}
void CBird::move(){
printf("bird can move \n") ;
}
void CFish::swim(){
printf("I can swim \n") ;
}
void CFish::move(){
printf("fish can move \n") ;
}
//CWaterBird继承CBrid和CFish类
class CWaterBird : public CBird ,public CFish {
public :
void run() ;
};
void CWaterBird ::run(){
printf("waterBird can run \n") ;
}
int main(int argc ,char* argv[]){
//实例化子类对象
CWaterBird waterBird ;
//调用breath方法
waterBird.breath() ;
printf("\n") ;
return 0 ;
}
上述代码中,由于采用了虚继承,CWaterBird中只有一个CAnimal对象,因此可以直接调用CAnimal 中的方法,编译器不会报错。
- 自学C++之类的继承
- OC之类的继承
- C++之类的继承
- swift之类的继承
- Java之类的继承
- C++之类的继承
- 用汇编的眼光看C++(之类继承)
- 用汇编的眼光看C++(之类继承)
- 用汇编的眼光看C++(之类继承)
- 用汇编的眼光看C++(之类继承)
- 黑马程序员——Objective-C学习之类的继承
- c++基础之类的继承
- [整理]JavaScript的继承之类式继承
- 用汇编的眼光看C++(之类继承) ,(之虚函数) .
- C++复习之类继承的控制访问
- 类对象继承之类的云云
- C++虚继承之类的实际大小
- C++之类的继承和多态
- TextView 和 Button
- bash组织成树型数据结构
- 今天遇到的十道面试题:Java 与 Servlet 方面
- 重启crontab服务
- C#异常处理
- 自学C++之类的继承
- 与书的相逢,是一场美丽的遇见
- Mac下使用gyp编译libpomelo静态库,并在cocos2dx项目中引用
- linux sort 命令详解
- 淘宝海量数据库之一:来自业务的挑战
- Lua 继承 多态 单利模式 面向对象
- Android Canvas类介绍
- 名古屋の一週間
- java heap space 设置