对于面向对象而言,我们很容易说出其三大特点:封装,继承,多态。
今天记录一下学习过程中golang与java多态的对比。
一、Golang
在golang中,多态主要是通过接口实现的。
可以按照同一的接口来调用不同的实现,这时接口变量就呈现不同的形态
并且相对于java,少了extends和implements关键字
举个例子
//声明一个Usb接口
type Usb interface {
//接口内声明了两个没有实现的方法
Start()
Stop()
}
type Phone struct {
Name string
}
//让Phone实现Usb接口的方法
func (p Phone) Start() {
fmt.Println("手机插入,开始工作...")
}
func (p Phone) Stop() {
fmt.Println("手机拔出,停止工作...")
}
type Camera struct {
Name string
}
//让Camera实现Usb接口的方法
func (ca Camera) Start() {
fmt.Println("相机插入,开始工作...")
}
func (ca Camera) Stop() {
fmt.Println("相机拔出,停止工作")
}
接口体现多态有两种方式:
- 多态参数
//编写电脑的Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口 (所谓实现了Usb接口 就是指实现了Usb接口的所有声明的方法)
func (computer Computer) Working(usb Usb) { //usb接口变量就体现出多态的特点 usb Usb称为多态参数
usb.Start()
usb.Stop()
}
func main(){
computer := Computer{}
phone := Phone{}
camera := Camera{}
//关键点 传入实现接口的类型
computer.Working(phone)
computer.Working(camera)
}
- 多态数组
func main() {
//使用多态数组
usbArr := [...]Usb{
Phone{"华为Mate 30 Pro"},
Phone{"小米10 Pro 至尊版"},
Camera{"索尼"},
}
fmt.Println(usbArr)
var computer Computer
for _, value := range usbArr {
computer.Working(value)
//传入的是哪个类型,就是哪个类型实现了多态
}
}
二、Java
#java中多态体现的格式:
父类类型 变量名 = new 子类对象
变量名.方法名()
#父类类型:指子类对象继承的父类类型,或者实现的父接口类型
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后的方法。简单的记为:编译看左(父类),执行看右(子类)
举个例子
public abstract class Animal {
//抽象方法,继承该类的子类需要重写
public abstract void eat();
}
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
public void watchHouse(){
System.out.println("狗看家");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Cat();
Animal a2 = new Dog();
a.eat(); //猫吃鱼
a2.eat(); //狗吃肉
//向下转型 为了防止转型失败 使用instanceof判断类型
if (a instanceof Cat){
Cat cat = (Cat)a;
cat.catchMouse();
}else if(a instanceof Dog) {
Dog dog = (Dog)a2;
dog.watchHouse();
}
}
}