Java多态

本文详细介绍了面向对象编程中的多态概念,包括子类继承父类、方法重写及父类变量指向子类对象等核心要素。并通过实例演示了如何实现多态以及动态绑定的工作原理。

多态

本质

多态是一种场景,此场景有如下特征:

  • 子类继承父类 (extends)
  • 在子类中重写了父类方法 (@override)
  • 父类变量指向子类对象(Father f = new Son();)
public class Animal {
    public String home = "earth";
    
    public void voice() {
        System.out.println("动物叫声");
    }
}

public class Dog extends Animal {
    public int life = 15;
    public String home = "狗窝";
    public String dogname = "小抖";
    
    @Override
    public void voice() {
        System.out.println("汪汪汪");
    }
    
    public void guard() {
        System.out.println("小抖看家");
    }
}

public class Cat extends Animal {
    public int life = 18;
    public String home = "猫舍";
    public String catname = "老猫";
    
    @Override
    public void voice() {
        System.out.println("喵喵喵");
    }
    
    public void Catch() {
        System.out.println("猫抓老鼠");
    }
}

public class Test {
    
    void raise(Animal animal) {
        animal.voice();
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        animal1.voice();					//汪汪汪
        animal2.voice();					//喵喵喵
        
        test.raise(animal1);				//汪汪汪
        test.raise(animal2);				//喵喵喵
        
        String s = animal1.dogname;			//Cannot resolve symbol 'dogname'
        animal1.guard();					//Cannot resolve method 'guard' in 'Animal'
        
        System.out.println(animal1.home);	//earth
        
        //向下转型
        Dog dog = (Dog)animal1;
    }
}

父类变量指向子类对象

public class Father {
    public int x = 1;

    public void fm() {
        System.out.println("hi, father");
    }
}

public class Son extends Father {
    private int y = 3;
	
    @Override
    public void fm() {
        System.out.println("hi, son");
    }
    
    void sm() {
        System.out.println("son method");
    }

    public static void main(String[] args) {                
        Father f = new Son();     
        System.out.println(f.x + f.y);	//Cannot resolve symbol 'y'     
        
        f.fm();							//hi son
        f.sm();							//Cannot resolve method 'sm' in 'Father'
    }
}

父类变量指向子类对象,通过该父类变量可使用的数据有:

  • 父类中的成员变量
  • 父类中的成员方法
  • 子类中重写后的新方法
f.fm();		//被调用的并非父类中的fm(),而是子类中重写后的fm()

不可以使用的数据有:

  • 子类中的成员变量
  • 子类中的成员方法(非重写父类的方法)

动态绑定

绑定

书写形式上,通过对象变量调用方法,实际运行时调用了某个方法,这个过程叫做绑定

  • 静态绑定:取决于变量的声明类型
  • 动态绑定:取决于变量的动态类型

本质

有多个存在继承关系的类,这些类组成一个继承链,在子类中重写父类方法

C1 -> C2 -> … -> Cn(C1继承自C2,C2继承自C3)

从左到右,依次查找并调用m()

Object o = new C1();
o.m();

书写o.m()时,最终被调用的是o的实际类型所对应的方法,此现象被称为动态绑定

//声明类型是Animal,实际类型是Dog
Animal animal = new Dog();
animal.voice();			//汪汪汪

向上转型

Animal animal = new Dog();

父类变量指向子类对象

向下转型

Animal animal = new Dog();
Dog dog = (Dog)animal;

将父类变量赋值给子类变量(父类变量引用的是子类对象)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值