C++中面向对象编程

C++中面向对象编程

面向过程即是面向函数的语言,当遇到复杂的问题时,把任务拆分。通过各个函数实现相对简单的功能,最后在主函数中调用。

一切皆对象,凡是证据一定空间的事物都可以称为对象。而面向对象的语言都是把任务当作对象去解决

这个世界是因为对象相互交互而运行的,而要实现一个比较复杂的系统,最好是模拟现实世界的规律即面向对象。

类的封装就是类本身,把属性(变量)和方法(函数)封装到class中;

类的继承 在C++中子类可以继承父类的一些属性和方法,站在巨人的肩膀上,瞬间拥有父类的一些东西;

多态 同一类事物,有相同的操作,但是具体到不同对象,结果不一样.在C++中基类常用虚函数实现共性的部分,在子类中对父类的继承并构造以后,同一个函数到不同对象中可以实现自己的功能。

类的继承

 父类--->子类
  基类--->派生类        
 
 
  继承,is a 关系 , 子类 is a 父类 , 狸花猫是猫,猫 is a 动物
     写代码的时候,要考虑现实情况.
 
 
  父子对象 成员同名的问题:
     class animal() {
     public:
       string sex;
       string kind;
       void show() { cout<<"in animal show()"<<endl;}
     private:
       int age;
     };
  
     class cat : public animal{
     public:
       string kind;
       void show() {cout<<"in cat show()"<<endl;}
     
     private:
     
     };
     
     cat xiaohua; 报错吗??? 可行吗??   ----见代码 ----父亲被隐藏
     xiaohua.show();
     cout<<xiaohua.kind <<endl;
     
     
#### public private protected 
 
1.修饰类成员
  class cat {
  public:  
     类内类外都可以访问
  
  protected:
     限制类外访问,和private区别只在继承方面
  
  private:
     限制类外访问
  
  };
  
2.继承方面
  生活中:  1.完全继承     子对象-自己用-给自己孩子-给外人     public :  子对象自己用,类外用,继承给孩子
        2.私有继承    自己用,限制继承--给外人非法        private :  子对象自己用
        3.保护继承    自己用,可以继承给孩子,给外人非法   protected:
 
     class animal {
     public:
       string kind;
       int weight;
       void show(){ cout<<"animal kind="<<kind<<" sex="<<sex<<endl;}
     protected:
       string sex;
       void sleep() {cout<<"animal sleep()"<<endl;}  
       
     private:
       string nothong;
       void ruce() {cout<<"animal ruce"<<endl;}
     };
 
######### public 继承   99% ######
     class cat:public animal {
       公有继承, 父亲的private部分 不能直接使用
              父亲的public protected成员 属性不变, 即父类中public成员在子类中还是public,protected还是不变
     
       效果等同于如下:  增加了父亲的代码
          --public:
            --string kind;
            --int weight;
            --void show(){ cout<<"animal kind="<<kind<<" sex="<<sex<<endl;}
          --protected:
            --string sex;
            --void sleep() {cout<<"animal sleep()"<<endl;}
     public:
       
     
     protected:
     
     private:
     
     };
  
  
     //类外访问
     cat xiaohua;
     xiaohua.kind = "lihuamao";  正确,父类public成员,通过public继承,再子类中还是pubic成员
     xiaohua.sex=" man"    ;   错误,父类的protected,通过public继承,在sub class中,还是保护成员,不允许类外访问
     xiaohua.nothong = "xx";    错误,父亲的私有不允许被子类访问
 
 
     class lihuamao:public cat {
       同理,因为animal的public protected成员,都已经属于cat中的public和protected,继续继承 
       可以使用 animal的public protectd成员
     
     };
     
####### 私有继承   ######### 限制类外访问 和继承 
  class cat: private animal {
     父亲的私有部分,cat肯定不能访问
     父亲的public protectd成员,都降级为private成员了
     效果等同于:
  
          --private:
            --string kind;
            --int weight;
            --void show(){ cout<<"animal kind="<<kind<<" sex="<<sex<<endl;}
          --private:
            --string sex;
            --void sleep() {cout<<"animal sleep()"<<endl;}
  
  };
  
  cat xiaohua;
  xiaohua.kind = "bosimao"; 非法,因为private继承,将所有成员降级为private
  
  class lihuamao : public cat{
     子类lihuamao中,不能直接访问 animal中的元素,###继承失败....
  
  };
  
################### 保护继承 ##################
  class cat:protectd animal{
     父类私有部分,肯定不行.
     父类public protectd 成员都降级为 protected成员 :
     效果等同于:
     
          --protectd:
            --string kind;
            --int weight;
            --void show(){ cout<<"animal kind="<<kind<<" sex="<<sex<<endl;}
          --protectd:
            --string sex;
            --void sleep() {cout<<"animal sleep()"<<endl;}  
  
  
  
  };
  
  cat xiaohua.kind = "xxx";  非法,因为protectd继承,父类所有成员都降级为protected,禁止类外访问
  
  class limaohua: public cat {
     孙子lihuamao继承
          --protectd:
            --string kind;
            --int weight;
            --void show(){ cout<<"animal kind="<<kind<<" sex="<<sex<<endl;}
          --protectd:
            --string sex;
            --void sleep() {cout<<"animal sleep()"<<endl;}  
  
  };

#include<iostream>
using namespace std;

class people{		//父类 描述事物的 普世的 通用的 都有的概念
public:
	string kind;
	int weight;
	
	people(){ cout<<"in people( )"<<endl; }
	people(string kind,int weight,string sex,int age) 
	{   cout<<"in people( ...)"<<endl;
		this->kind=kind; this->weight=weight;this->sex=sex;this->age=age;
	}
	
	
	~people() {cout<<"~people()"<<endl;}
	
	void eat(void){cout<<"people eat()"<<endl;}
	void run(void){cout<<"people run()"<<endl; }
	
	void set_sex(string sex) {this->sex=sex;}
	string get_sex() {return sex;}
	void set_age(int age) {this->age=age;}
	int get_age(void){return age;}
private:	//限制类外访问,包括限制 子对象的直接访问
	string sex;
	int age;
	
	void la(void){cout<<"people la()"<<endl;}
};

/*
	class 子类:父类 {
		父类的东西
		子类的新东西
	}

*/
class student: public  people{    
	//已经拥有了people的##所有东西##,只是父亲的private部分不可以直接访问 
	//然后我们只需要添加子类特有的即可
public:
	string name;
	/*
	####构造函数:
		子类的构造函数在执行的时候,首先去寻找并执行父类的构造函数 (初始化父亲的那一部分)
		之后,再执行子类的部分(初始化子类的部分)
		
		子类构造,如何执行调用父亲的哪一个构造.......		如果不指定,调用父类的默认构造
			子类构造(参数1,参数2,参数3....):父亲构造(arg1,arg2,....)
			{
				只用来初始化子类特有的
			}
	*/
	student() {}   //会call father's default structure
	student(string name,int age,string sex) : people("student type" ,5,sex,age)
	{
		cout<<"in student(...)"<<endl;
		this->name=name;		 
	}
	
	/*
		析构函数:  当子对象被销毁,执行子对象的析构, 在子对象析构执行完毕后,会自动调用父对象的析构
	
	*/
	~student() 
	{  
		cout<<"~student()"<<endl; 
		//调用父亲的析构,不需要写,g++自动帮你添加代码
	}
	
	void show(){ cout<<"name="<<name<<" sex="<<get_sex()<<" age="<<get_age()<<endl;}
	
	void studentStudy(void){cout<<"student study" <<endl;}
	void studentTest(void){cout<<"student test"<<endl;}
private:
	void run(void){cout<<"student run"<<endl;}
	string color;
};

int main()
{
	//student xiaohuangng;
	student xiaohuang("huang",3,"woman");    /* 当子类对象产生,立即出发子类构造, 
											子对象构造函数,首先寻找父类构造函数并执行,之后在执行自己的*/
	
	xiaohuang.show();
	
	
	cout<<"####### father class private show##########"<<endl;
	/* xiaohuang.sex = "man";  非法的
		父类有私有成员, 父类希望这些private都只能在父类中使用.
		子类是不能够直接访问的( 子类中有这些东西 ),如果子类想访问,
		只能通过父类提供的public 方法
	*/
	xiaohuang.set_sex("man");
	cout<<"xiaohuangng sex="<<xiaohuangng.get_sex()<<endl;
	
	cout<<"########## public member show########"<<endl;
	xiaohuang.type= "student type";
	xiaohuang.weight=3;
	xiaohuang.name="xiaohuang";
	xiaohuang.eat();
	xiaohuang.studentchMouse();
	
	//main退出之后,进程技术,释放所有空间(包括 xiaohuang, ),执行xiaohuang的析构( ~student()  )
}



多态: 是面向对象中一种很重要的特性.

 同一类事物,有相同的操作,但是具体到不同对象,结果不一样.
 生活中到处都是多态.
 父类的run函数要允许子类覆盖它: 即子类也要实现run
     如何允许子类覆盖掉该函数呢?
     使用virtual修饰函数, 该函数为一个 虚函数,允许子类覆盖.
 
  使用父类指针指向子类对象, 可以屏蔽掉子类的 个性,只关注整体的共性.
  纯虚函数:
     父类的虚函数,一般在子类中都会重新实现,被覆盖掉. 我们几乎不会使用父亲虚函数
     就没有必要实现了,  我们可以直接不写.   virtual void run() = 0;
     
     
  
  //我们发现父类的虚函数 几乎不会被使用,可以不写,直接给0
  //这样的函数,称为   纯虚函数:虚函数没有函数体/实现 
  //拥有纯虚函数的类,是不完整的( 因为函数没有完成),这种类 称为 虚基类
  // person xiaowang; 非法,因为虚基类 不完整,大小都确定的.
  // person * p;  合法的.  虚基类可以定义指针,因为 指针大小固定
  
  虚析构:
  
   问题: p是父类指针,虽然指向子类对象,但是只能访问父类的部分,所以这里调用的是父类的析构
        子类部分没法释放,怎么办
        基类的析构改为 虚函数 
              
            这是一个很常用的方法:   
              如果可以,所有的析构 都要写成虚函数.
#include<iostream>
using namespace std;

class animal{
public:
	/*父类的run函数要允许子类覆盖它: 即子类也要实现run
		如何允许子类覆盖掉该函数呢?
		使用virtual修饰函数, 该函数为一个 虚函数,允许子类覆盖.
	*/
	virtual void run() {cout<<"animal run"<<endl;}
	void bark(){cout<<"animal bark"<<endl;}
private:
	string kind;
};
	
class cat:public animal {
public:
	void run() {cout<<"cat run"<<endl;}   //会覆盖掉 父类的 虚函数
	void catchMouse(){cout<<"cat catchMouse"<<endl;}
private:
	string name;
};
		
	

class dog:public animal {
public:
	void run(){cout<<"dog run"<<endl;}
	void watchdog(){ cout<<"watch dog"<<endl;}
private:
	void goupao(){ }
};

int main()
{
	dog xiaowang;
	xiaowang.run();		// dog run
	
	cat xiaohua;
	xiaohua.run();		//  打印cat run;
	
	animal *pt = &xiaowang;
	pt->run();  //打印结果是  子类的run
	/*
		原理是:  
			子类的 run函数覆盖了父类的run(父类的run"消失")了.
	*/
}

继承和多态的实例

#include<iostream>
using namespace std;
/*
	定义一个人类为 基类,   包含姓名,年龄,性别ID,工作 娱乐方法;    定义子类,
		实现律师(增加属性方法)     完成工作 娱乐等方法
		码农子类(增加属性方法),  完成工作 娱乐等方法
		完成构造和析构,至少三种(父类构造)	

*/

class person{
public:
	virtual void work()  =0;
    //我们发现父类的虚函数 几乎不会被使用,可以不写,直接给0
	virtual void funy()  =0;	
    //这样的函数,称为   纯虚函数:虚函数没有函数体/实现 
	//拥有纯虚函数的类,是不完整的( 因为函数没有完成),这种类 称为 虚基类
	person() { }				
    // person xiaowang; 非法,因为虚基类 不完整,大小都确定的.					
    // person * p;  合法的.  虚基类可以定义指针,因为 指针大小固定
person(string xname,string xsex,intxage):name(xname),age(xage),sex(xsex)
{  }
		
private:
	string name;
	int age;
	string sex;
};

class lawer:public person {
public:
	void work() { cout<<" da guan si "<<endl;}
	void funy() { cout<<" bei law book"<<endl;}

	lawer(string name,int workid,int age,string sex):person(name,sex,age )
	{
		this->workid=workid;
	}
private:
	int workid;

};

class coder :public person {
public:
	void work() { cout<<" coding "<<endl;}
	void funy() { cout<<" shua github "<<endl;}
private:
	string workage;
};


int main()
{
	
	person *p = new  lawer("wanglushi",123789,39,"man");
	p->work();
	p->funy();
	
	delete p;
	
	p = new coder ;
	p->work();
	p->funy();
	
	delete p;	
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小镇春风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值