三种继承方式

1.什么是继承?

继承是创建新类的方式,新建的类可以继承一个或者多个父类,父类又称基类或超类,新建的类称为派生类或子类

2.继承和派生的目的

  • 继承的目的:代码设计的重用
  • 派生的目的:功能的扩展/更改

好处在于代码的重用性和可扩展性。通过继承可以利用别人做过一些类似的研究,和己有的一些分析,解决方法。重用这些代码是自己的开发站在巨人的肩膀上。当有新的问题或对问题有了新的认识,也能高效改造和扩充。

3.继承的三种方式

  • publicprivateprotected

三种继承方式 基类的权限如下:

java继承父类排除某些属性 继承父类方法_继承方式

一般情况下,我们使用最多的是public继承方式。当我们有特殊需求是才会使用private和protected继承方式。

基本语法:

class 派生名称:继承方式 基类1,继承方式 基类2,...{

其他

}

  • 一个实例:

为了简便,把类的定义和实现放在了一起,方便观察。

但在实际练习或者开发中,应养成良好的习惯和思想,把类的定义,实现和测试分开。

注:此例跳过了构造函数和析构函数,放在了最后实验。

#include<iostream>
	using namespace std;
	
	
	//三种继承方式
	
	
	class Base {//父类
	private:
		int b=1;
	public:
		void show() { cout << "Base's show" << endl; }
	protected:
		void add() { cout << "Base's add" << endl; }
	};
	
	class Son1 :public Base {//子类1  public继承于Base
	public:
		//吸收基类成员的派生过程
		//cout << "Base.b=" << b;  //虽然继承下了父类的private,但是不可以访问
	};
	
	class Son2 :private Base {//子类2    private继承于Base
	public:
		void show() {      //改造基类成员派生过程
			Base::show();//访问父类public中的函数,因为和父类公有函数show同名,所以要通过作用域访问
			//show();  //错误访问方式
			add();//访问父类protected的函数
			cout << "Son2's show" << endl;
			//cout << "Base.b=" << b;  //虽然继承下了父类的private,但是不可以访问
		}
	};
	
	class Son3 :protected Base {//子类3    protected继承于Base
	public:
		void show3() {  //新添成员的派生过程
			show();//也可以访问父类public中的函数
			add();//访问父类protected的函数
			cout << "Son3's show" << endl;
			//cout << "Base.b=" << b;  //虽然继承下了父类的private,但是不可以访问
		}
	};
	
	int main() {
		Son1 s1;
		s1.show();//子类s1调用的是父类的show()
		cout << "----------" << endl;
		Son2 s2;
		s2.show();//私有继承方式,所以不能调用父类的show(),  且是改造父类成员的派生过程,已经屏蔽了父类的show()
		cout << "----------" << endl;
		Son3 s3;
		s3.show3();//保护继承方式,子类s3也不能调用到父类的show()
		
		return 0;
	}

对于各种继承方式,父类的private是继承下来,但是不可访问。

java继承父类排除某些属性 继承父类方法_java继承父类排除某些属性_02

经调试可以在子类中找到父类的存储b的空间:

java继承父类排除某些属性 继承父类方法_继承方式_03

运行结果:

java继承父类排除某些属性 继承父类方法_子类_04

以上继承是单继承。

  • 也可以多继承,就上个例子来说,可以这样写:
#include<iostream>
  using namespace std;
  
  class Base {//父类
  private:
  	int b=1;
  public:
  	void show() { cout << "Base's show" << endl; }
  protected:
  	void add() { cout << "Base's add" << endl; }
  };
  class Base1 { //父类
  private:
  public:
  	void pretend() { cout << "Base1's pretend" << endl; }
  };

  class Son4 :public Base, public Base1 {// 子类4   多继承
  public:
  	void pretend4() { cout << "Son4's pretend" << endl; }
  };
  int main(){
  	Son4 s4;
  	s4.pretend();
  	
  	s4.show();
  	//s4.add();   //子类s4是公有继承Base,在子类里是protected成员,对象不可以访问protected成员函数
  	return 0;
  }

若果把s4.add()注释取消则会报错。如图:

java继承父类排除某些属性 继承父类方法_java继承父类排除某些属性_05

结果:

java继承父类排除某些属性 继承父类方法_继承方式_06

  • 多重继承
#include<iostream>
  using namespace std;
  
  
  class Base {//父类
  private:
  	int b=1;
  public:
  	void show() { cout << "Base's show" << endl; }
  protected:
  	void add() { cout << "Base's add" << endl; }
  };
  
  class Son2 :private Base {//子类2    private继承于Base
  public:
  	
  	void pretend2() { cout << "Son2's pretend" << endl; }
  };
  
  class Son3 :protected Base {//子类3    protected继承于Base
  public:
  	void show3() {  //新添成员的派生过程
  		show();//也可以访问父类public中的函数
  		add();//访问父类protected的函数
  		cout << "Son3's show" << endl;
  	}
  };

  class Son5:public Son2{  
  public:
  	void show5() { 
  		//show();   //因为直接父类是私有继承,后代即便是公有继承也无法访问"祖父"的成员函数
  		pretend2(); //调用直接父类的公有函数
  	}
  };

  class Son6 :public Son3 { 
  public:
  	void show6() {
  		show();//调用间接父类Base的公有函数
  		add();//调用间接父类Base的保护函数
  
  		show3();//调用直接父类Son3的公有函数
  	}
  };
  int main() {
  	Son5 s5;
  	s5.show5();
  	cout << "----------" << endl;
  	Son6 s6;
  	s6.show6();
  	//s6.show(); //因为直接父类是保护继承,所以无法访问间接父类的公有函数
  	return 0;
  }

结果:

java继承父类排除某些属性 继承父类方法_父类_07

  • 继承中的构造函数和析构函数
#include<iostream>
  using namespace std;

  class Base2 {
  public:
  	Base2() { cout << "Base2 start" << endl; }//构造函数
  	~Base2() { cout << "Bsae2 end" << endl; }//析构函数
  };

  class Son7:public Base2 {
  public:
  	Son7(){ cout << "Son7 start" << endl; }
  	~Son7() { cout << "Son7 end" << endl; }
  };

  int main() {
  	Son7 s7;
  	return 0;
  }

结果:

java继承父类排除某些属性 继承父类方法_父类_08

小结:

在继承过程中,先构造父类,再构造子类;先析构子类,再析构父类。

总结:

在类的继承和派生过程中,有三种继承方式,三种派生过程,子类和子类的对象访问权限不同。

  • 子类拥有父类的所有成员变量和成员函数;(继承)
  • 子类可以拥有父类没有的方法和属性;(派生)
  • 子类对象可当作父类对象使用;(public继承方式)