1.靜態父類方法
在C++中無法重寫靜態方法。其實子類和父類存在同名的靜態方法,它們是兩個獨立的方法。靜態方法是屬於類的,調用是通過類名而不是對象,雖然也可以通過對象調用靜態方法,也就相當與class::function,但是C++在調用靜態方法時,不關心對象實際是什麼,只是關心編譯時間的類型。如下的結果:
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUPER_HPP#define SUPER_HPP#include <iostream>/** * @brief The Super class 超類 父類 */class Super{public: Super() {} virtual ~Super() {} virtual void fun(const std::string &arg = "Super") const { std::cout << arg << '\n'; } static void staticFun() { std::cout << "Super Static Function!\n"; }};#endif // SUPER_HPP/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUB_HPP#define SUB_HPP#include "super.hpp"/** * @brief The Sub class 子類 */class Sub : public Super{public: Sub():Super() {} virtual void fun(const std::string &arg = "Sub") const{ std::cout << arg << '\n'; } static void staticFun() { std::cout << "Sub Static Function!\n"; }};#endif // SUB_HPP#include "sub.hpp"int main(){ Super::staticFun(); Sub::staticFun(); Sub su; Super &s = su; s.staticFun(); return 0;}
所以子類不要重寫靜態方法,那是新的方法,還有就是靜態方法調用通過類名。
2.父類方法被重載
當指定名稱以及一組參數重寫某個方法時,編譯器會隱式的隱藏父類中的同名方法的所有其他執行個體。它的意思是,你竟然重寫了其中的一個,那麼重載的你也應該全部重寫,因為是相同的方法名,功能其實也應該是相同的,只是參數不一樣而已,你竟然改變一個方法,那說明功能全部要改變。
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUPER_HPP#define SUPER_HPP#include <iostream>/** * @brief The Super class 超類 父類 */class Super{public: Super() {} virtual ~Super() {} virtual void fun(const std::string &arg = "Super") const { std::cout << arg << '\n'; } static void staticFun() { std::cout << "Super Static Function!\n"; } //下面為兩個重載的函數 virtual void overload() const { std::cout << "Super overload()\n"; } virtual void overload(int t) const { std::cout << "Super overload(int) and arg is " << t << '\n'; }};#endif // SUPER_HPP/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUB_HPP#define SUB_HPP#include "super.hpp"/** * @brief The Sub class 子類 */class Sub : public Super{public: Sub():Super() {} virtual void fun(const std::string &arg = "Sub") const{ std::cout << arg << '\n'; } static void staticFun() { std::cout << "Sub Static Function!\n"; } //Sub重寫了其中的一個 virtual void overload() const { std::cout << "Sub overload()\n"; }};#endif // SUB_HPP#include "sub.hpp"int main(){ Sub su; su.overload(8); return 0;}
一個Sub的對象調用了形參為int的函數,編譯時間報no matching method of 'overload(int)'的錯誤,說明,在子類中的父類重載方法已經被隱式的隱藏了。
但是你實在需要這些問題,而你又不需要重寫,可以使用using語句,添加一句using
Super::overload,標明我接受父類所有的重載函數。
3.重寫private和protected父類方法
訪問限定符只是限定訪問和重寫沒有關係。其實這種重寫private和protected方法是一種設計模式,被稱為模板。在做android開發中,Activity類有protected
void onCreate方法需要重寫,就是在一個類繼承體系中,這幾個操作是固定有的,在沒有子類實現的行為是不一樣的。再舉個例子,在Qt中一個QWidget的子類可以需要處理一些事件,但是每個子類對響應事件可能是不同的。
4.父類方法具有預設參數值
在C++中解析預設參數值是根據描述對象的運算式類型綁定預設參數,而不是根據實際的物件類型綁定參數。這點和上述提到的第一點很像。
#include "sub.hpp"int main(){ Sub su; Super &s = su; s.fun(); return 0;}
5.子類函數具有不同的存取層級
訪問基本的改變無非兩種,要不加強,要不放鬆。可以有如下形式,降低存取層級可以讓子類為存取層級高的提供一個public修飾的包裹函數,還有就是直接在子類中重寫方法和修改訪問限定符。提高存取層級,只能在子類中修改訪問限定符,可是有時也不能做到完全的提高。
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUPER_HPP#define SUPER_HPP#include <iostream>/** * @brief The Super class 超類 父類 */class Super{public: Super() {} virtual ~Super() {} //public 存取層級的函數 virtual void fun() const { std::cout << "public" << '\n'; } static void staticFun() { std::cout << "Super Static Function!\n"; } //下面為兩個重載的函數 virtual void overload() const { std::cout << "Super overload()\n"; } virtual void overload(int t) const { std::cout << "Super overload(int) and arg is " << t << '\n'; } virtual void overload(double t) const { std::cout << "Super overload(double) and arg is " << t << '\n'; }};#endif // SUPER_HPP/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef SUB_HPP#define SUB_HPP#include "super.hpp"/** * @brief The Sub class 子類 */class Sub : public Super{public: Sub():Super() {} static void staticFun() { std::cout << "Sub Static Function!\n"; } //Sub重寫了其中的一個 virtual void overload() const { std::cout << "Sub overload()\n"; } using Super::overload;protected:private: //private virtual void fun() const{ std::cout << "private" << '\n'; }};#endif // SUB_HPP#include "sub.hpp"int main(){ Sub su; // su.fun(); Super &s = su; s.fun(); return 0;}