返回
通俗易懂:继承易错点分析
后端
2024-01-22 06:09:57
了解继承易错点,少走弯路,更显代码功底。
继承易错点:基类private成员的继承
-
基类private成员的访问权限:
- 私有成员只能在定义它的类及其友元类中访问。
- 错误示例:
class Base { private int privateMember = 10; } class Derived extends Base { public void accessPrivateMember() { System.out.println(privateMember); // 编译器错误:privateMember不可访问 } }
-
基类private方法的访问权限:
- 私有方法只能在定义它的类中调用。
- 错误示例:
class Base { private void privateMethod() { System.out.println("Private method"); } } class Derived extends Base { public void accessPrivateMethod() { privateMethod(); // 编译器错误:privateMethod不可访问 } }
解决方法:
- 如果需要在派生类中访问基类的私有成员或方法,可以使用友元类。友元类可以访问另一个类的私有成员和方法。
- 谨慎使用私有成员和方法。在需要严格控制访问权限时才使用私有成员和方法。
- 在继承中,基类的protected成员在派生类中是可见的,但不能直接访问。需要通过基类指针或引用来访问。
继承易错点:构造函数和析构函数的继承
-
构造函数的继承:
- 构造函数不能被继承。
- 派生类不能显式调用基类的构造函数。
- 错误示例:
class Base { public Base() { System.out.println("Base constructor"); } } class Derived extends Base { public Derived() { Base(); // 编译器错误:不能调用基类的构造函数 } }
-
析构函数的继承:
- 析构函数可以被继承。
- 派生类的析构函数会自动调用基类的析构函数。
- 错误示例:
class Base { ~Base() { System.out.println("Base destructor"); } } class Derived extends Base { ~Derived() { // 忘记调用基类的析构函数 } }
解决方法:
- 派生类的构造函数应该显式调用基类的构造函数。
- 派生类的析构函数应该显式调用基类的析构函数。
继承易错点:基类的成员覆盖
-
成员覆盖(Overriding):
- 派生类可以覆盖基类的非私有成员。
- 覆盖的成员必须具有相同的名称和参数类型。
- 覆盖的成员可以具有不同的访问权限,但不能比基类的成员更严格。
- 错误示例:
class Base { public void publicMethod() { System.out.println("Base public method"); } } class Derived extends Base { private void publicMethod() { // 编译器错误:覆盖的成员不能比基类的成员更严格 System.out.println("Derived private method"); } }
-
虚函数(Virtual Function):
- 虚函数是允许派生类覆盖的函数。
- 虚函数通常使用virtual来声明。
- 虚函数可以在派生类中被重新定义,以实现不同的功能。
- 错误示例:
class Base { public virtual void virtualMethod() { System.out.println("Base virtual method"); } }; class Derived : public Base { public virtual void virtualMethod() { System.out.println("Derived virtual method"); } }; class GrandDerived : public Derived { public void virtualMethod() { // 编译器错误:GrandDerived类没有覆盖virtualMethod System.out.println("GrandDerived virtual method"); } };
解决方法:
- 确保派生类的覆盖成员具有相同的名称和参数类型。
- 确保派生类的覆盖成员可以具有不同的访问权限,但不能比基类的成员更严格。
- 使用virtual关键字来声明虚函数,以便允许派生类覆盖。
- 确保派生类覆盖了基类的虚函数,否则将导致编译器错误。
结论
继承是面向对象编程中的重要概念,但同时也是一个容易出错的地方。了解继承中的易错点,可以避免在编码中踩坑,写出更健壮、更可靠的代码。