C++ 与Java中的多态

多态

定义就是 就是基于同一个接口,使用不同的实例而执行不同操作

多个类都继承同一个父类 其中都重写或者继承了父类中的一个的成员函数,虽然名称相同 ,但是函数体不同,根据调用 此函数的对象实例的不同执行其对象所属的类中的成员函数,函数体不同,表现出来的操作自然不同 称为多态 (这是我自己理解的)

Java中的例子:

USU接口:

public interface IUSB {
	public void work();// 接入USB接口的设备工作方法
}

 键盘实现类

public class KeyboardImpl implements IUSB {

	public void work() { // 键盘的工作
		System.out.println("键盘正在工作");

	}
}

 鼠标实现类

public class MouseImpl implements IUSB {

	public void work() { // 鼠标正在工作
		System.out.println("鼠标正在工作");
	}

}

 Computer类

public class Computer {
	public static void main(String[] args) {
		Computer computer = new Computer();
		KeyboardImpl keyboard = new KeyboardImpl(); // 创建一个键盘对象
		MouseImpl mouseImpl = new MouseImpl();// 创建 一个鼠标对象
		computer.DetectTheworkOfUSB(mouseImpl); // 计算机对USB发出探测并开始USB接口的工作,即鼠标接入USB接口
		computer.DetectTheworkOfUSB(keyboard);// 计算机对USB发出探测并开始USB接口的工作,即键盘接入USB接口
	}

	public void DetectTheworkOfUSB(IUSB usb) {
                   //鼠标和键盘都向上转型为同一个类型IUSB,但是调用work()却表现不同,这就是多态。
		usb.work(); // 实际上在这里他判断了usb究竟是keyboard还是mouse的实例,根据此实例所属的类调用keyboard还是mouse中的work()成员方法.
					// 于是传入的参数不同 将执行不同的work方法 展现出不同的效果 ,这就是多态
	}
}

输出:

鼠标正在工作
键盘正在工作
 

 可以看出java中的接口就有点类似于USB接口,厂家不用管你用什么设备插入USB接口,只要给出一个统一规定规定这些设备都得实现一个work方法,计算机可以只需写一个方法即DetectTheWorkOfUSB(IUSB usb) 直接对USB接口进行操作,而不需要关心插入USB接口的到底是鼠标还是键盘或者是其他乱七八糟的东西,对这些设备的类型判断都在DetectTheWorkOfUSB(IUSB usb)内部进行并向上层屏蔽, 实际上在这里他判断了usb究竟是keyboard还是mouse的实例,根据此实例所属的类调用keyboard还是mouse中的work()成员方法.于是传入的参数不同 将执行不同的work方法 展现出不同的效果 ,这就是多态。。实际上在传入参数时进行了一次自动类型转换,相当于判断了是什么类型的设备,也可以用另一种方式实现:如:

修改Computer类中的DetectTheWorkOfUSB(IUSB usb)方法为:

public void DetectTheworkOfUSB(IUSB usb) {
		if (usb instanceof MouseImpl) {// 如果是键盘类型 则执行键盘的work方法
			MouseImpl mouse = (MouseImpl) usb;
			mouse.work();
		} else if (usb instanceof KeyboardImpl) {// 如果是鼠标类型 则执行鼠标的work方法
			KeyboardImpl keyboard = (KeyboardImpl) usb;
			keyboard.work();
		}
        //如需要增加设备 只需在此增加一个判断即可

	}

这个方法向上屏蔽了判断设备类型的细节,向上层提供了一个抽象统一的接口。也体现了面向对象中抽象(数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制,注意区分,数据封装是一种把数据和操作数据的函数捆绑在一起的机制)的特点。

还可得出接口的作用:向其实现类提供了一个统一的实现方法,实现类一般会向上转型成接口(或者抽象类)传参进其他方法里根据对象所属实现类的不同而执行名称相同但函数体不同的方法,更好的实现多态。

设想如果没有接口该会如何:

鼠标和键盘类没有变只是不再实现IUSB接口里的方法

Computer类将变成

public class Computer {
	public static void main(String[] args) {
		Computer computer=new Computer();
		KeyboardImpl keyboard = new KeyboardImpl();
		MouseImpl mouse = new MouseImpl();
		computer.workOfMouse(mouse);
		computer.workOfKeyboard(keyboard);
	}

	public void workOfKeyboard(KeyboardImpl keyboard) {
		keyboard.work();
		
	}

	public void workOfMouse(MouseImpl mouse) {
		mouse.work();
	}
	

}

对于每种设备都得写一个专门的方法供计算机来控制设备的工作 现在设备有成千上万中 如果增加了一百台,则需增加一百个专门用于该设备的方法,灵活性极低 而且计算机 也必须实现类型的判断。

C++中的多态:

实质是差不多 但是稍有不同的是 C++中子类重写父类的方法 ,需要父类为虚函数

纯虚函数类似于接口

形成多态必须具备三个条件:

1、必须存在继承关系;

2、继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字Virtual声明的函数,在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);

3、存在基类类型的指针或者引用,通过该指针或引用调用虚函数;

如果使用基类类型的指针会出现如下问题:

#include<iostream>
using namespace std;
class A{
	public:
		void function(){
			cout<<"sdsd"<<endl;
		}
};

class B:public A{
	public:
		void function(){
			cout<<"ssss"<<endl;
		}
};
int main(){
	A  *a;
	B b;
	a=&b;
	a->function();
	
	return 0;
}

虽然已经指向了B类的对象b 但是他还是输出的sdsd,这是因为调用函数function() 被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 function() 函数在程序编译期间就已经设置好了。如果要调用到子类的function方法实现重写和多态 就得在基类的方法定义前加上virtual即可成功输出ssss.加上virtual相当于告诉编译器别早绑定,而是在程序中任意点可以根据所调用的对象类型来选择调用的函数(多态),这种操作被称为动态链接,或后期绑定。如果在基类中不能对要被继承重写的虚函数作出有意义的定义或者实现,一般将其定义为纯虚函数

例如上述A类中的function() 函数体如果没有意义可以定义为virtual void function()=0;这就和IUSB中的接口方法差不多了。“=0”即告诉编译器此函数没有函数体。

如果一个类中有一个或者一个以上的纯虚函数 则被称为抽象类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。其子类要继承也必须实现每个虚函数,否则还是一个抽象类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值