多态的2个缺陷

最近在研读<<Thinking in Java>>......

多态的2个缺陷,其一:对私有方法的“覆盖”。只有非private方法才可以覆盖,因为private方法会被自动默认为是final方法。


public class Father {

private void f() {
System.out.println("Father's f()");
}

public void p() {
System.out.println("Father's p()");
}

public static void main(String[] args) {
Father f = new Sun();
f.f();//Father's f()
f.p();//Sun's p()
}

}

class Sun extends Father {

public void f() {
System.out.println("Sun's f()");
}

public void p() {
System.out.println("Sun's p()");
}

}


其二:域与静态方法不具多态性。因为域是分配有存储空间的,父类与子类的域名虽然相同,但其存储空间不同。静态方法也同样道理。


public class FieldAccess {

public static void main(String[] args) {
Super sup = new Sub();
System.out.println(sup.field);//0
System.out.println(sup.getField());//1
System.out.println(sup.dynamicGet());//Sub's dynamicGet
System.out.println(sup.staticGet());//Super's staticGet

Sub sub = new Sub();
System.out.println(sub.field);//1
System.out.println(sub.getField());//1
System.out.println(sub.getSuperField());//0

}

}

class Super {

public int field = 0;

public int getField() {
return field;
}

public String dynamicGet() {
return "Super's dynamicGet";
}

public static String staticGet() {
return "Super's staticGet";
}
}

class Sub extends Super {

public int field = 1;

public int getField() {
return field;
}

public int getSuperField() {
return super.field;
}

public String dynamicGet() {
return "Sub's dynamicGet";
}

public static String staticGet() {
return "Sub's staticGet";
}
}
提供了一个基于51单片机的RFID门禁系统的完整资源文件,包括PCB图、原理图、论文以及源程序。该系统设计由单片机、RFID-RC522频射卡模块、LCD显示、灯控电路、蜂鸣器报警电路、存储模块和按键组成。系统支持通过密码和刷卡两种方式进行门禁控制,灯亮表示开门成功,蜂鸣器响表示开门失败。 资源内容 PCB图:包含系统的PCB设计图,方便用户进行硬件电路的制作和调试。 原理图:详细展示了系统的电路连接和模块布局,帮助用户理解系统的工作原理。 论文:提供了系统的详细设计思路、实现方法以及测试结果,适合学习和研究使用。 源程序:包含系统的全部源代码,用户可以根据需要进行修改和优化。 系统功能 刷卡开门:用户可以通过刷RFID卡进行门禁控制,系统会自动识别卡片并判断是否允许开门。 密码开门:用户可以通过输入预设密码进行门禁控制,系统会验证密码的正确性。 状态显示:系统通过LCD显示屏显示当前状态,如刷卡成功、密码错误等。 灯光提示:灯亮表示开门成功,灯灭表示开门失败或未操作。 蜂鸣器报警:当刷卡或密码输入错误时,蜂鸣器会发出报警声,提示用户操作失败。 适用人群 电子工程、自动化等相关专业的学生和研究人员。 对单片机和RFID技术感兴趣的爱好者。 需要开发类似门禁系统的工程师和开发者。
C++中封装、继承、多态作为面向对象编程的核心特性,具有重要意义。 封装旨在实现代码的模块化并增强安全性。通过封装,类以外的程序无法直接访问或修改类的成员,只能通过成员对应的方法来操作,这就是数据封装。同时,封装还隐藏了方法实现的具体细节,仅提供接口,即便内容修改也不会影响外部调用,即方法封装。如此一来,代码的内部实现被保护,外部调用者只需关注接口,提高了代码的可维护性和安全性[^2]。 继承的目的是重用和扩展现有的代码模块。一个类继承另一个类后,会继承其声明的成员和函数,避免了重新定义的麻烦,实现了代码的重用。同时,派生类还能添加自身的属性和方法,从而扩展父类功能。不过,继承也存在一定缺陷,父类的变化会导致子类必须随之改变,增加了代码的耦合性[^2]。 多态则实现了接口的复用,体现为一个接口多种实现。可以用父类型的指针指向子类的实例,然后通过父类指针调用实际子类的成员函数。C++的多态性通过虚函数实现,虚函数允许子类重新定义成员函数,这种子类重新定义父类函数的做法称为覆盖或重写。此外,还有编译时多态,主要指方法的重载,在编译器编译期间就能确定函数的调用地址并产生代码,是静态的;运行时多态则通过虚函数在运行时确定调用地址[^2]。 以下是简单示例代码: ```cpp #include <iostream> // 封装示例 class EncapsulationExample { private: int data; // 数据封装 public: EncapsulationExample(int d) : data(d) {} int getData() const { return data; } // 提供接口访问私有成员 void setData(int d) { data = d; } }; // 继承示例 class Base { public: int baseData; Base(int d) : baseData(d) {} void baseFunction() { std::cout << "Base function" << std::endl; } }; class Derived : public Base { public: int derivedData; Derived(int b, int d) : Base(b), derivedData(d) {} void derivedFunction() { std::cout << "Derived function" << std::endl; } }; // 多态示例 class Shape { public: virtual void draw() { std::cout << "Drawing a shape" << std::endl; } }; class Circle : public Shape { public: void draw() override { std::cout << "Drawing a circle" << std::endl; } }; class Square : public Shape { public: void draw() override { std::cout << "Drawing a square" << std::endl; } }; int main() { // 封装测试 EncapsulationExample enc(10); std::cout << "Encapsulated data: " << enc.getData() << std::endl; // 继承测试 Derived der(1, 2); der.baseFunction(); der.derivedFunction(); // 多态测试 Shape* shape1 = new Circle(); Shape* shape2 = new Square(); shape1->draw(); shape2->draw(); delete shape1; delete shape2; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值