1.多态
我们知道继承关系是一种”is A”的关系,也就说子类是父类的一种特殊情况
问题: 子类的对象是动物?
既然子类是一种特殊的父类,那么我们可不可以认为狗对象/猫对象就是动物类型的对象.
Animal d = new Dog(); //创建一只狗对象
Animal c = new Cat(); //创建一只猫对象
--------------------------------------------------------------
当我的代码变成以下的样子的时候,多态就产生了:
Animal a = new Dog();
对象(a)具有两种类型:
编译类型: 声明对象变量的类型,Animal,表示把对象看出什么类型.
运行类型: 对象的真实类型,Dog.运行类型--->对象的真实类型.
编译类型必须是运行类型的父类/或相同.
当编译类型和运行类型不同的时候,多态就出现了.
当编译类型和运行类型不同的时候,多态就出现了.
所谓多态: 对象具有多种形态,对象可以存在不同的形式.
Animal a = null;
a = new Dog(); //a此时表示Dog类型的形态
a = new Cat(); //a此时表示Cat类型的形态
--------------------------------------------------------------------
多态的前提:可以是继承关系(类和类)/也可以是实现关系(接口和实现类),在开发中多态一般都指第二种.
--------------------------------------------------------------------
我家里养了一只动物,名字叫”乖乖”,此时”乖乖”可以有多种形态;
乖乖 是狗, 乖乖的叫声: one one one.
乖乖 是猫, 乖乖的叫声: 喵 喵 喵.
多态的特点:
把子类对象赋给父类变量,在运行时期会表现出具体的子类特征(调用子类的方法).
Animal a = new Dog();
2多态的好处:
需求:给饲养员提供一个喂养动物的方法,用于喂养动物.没有多态:
发现,针对于不同类型的动物,我们得提供不同的feed方法来喂养.我想,只提供一个方法,就能统一喂养所有动物
.
存在多态:
统一了喂养动物的行为。
从上述例子,可以得知多态的作用:当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化。
3.多态时方法调用问题
多态时方法调用问题:
前提:必须先存在多态情况
存在父类:SuperClass,子类:SubClass,方法:doWork.
--------------------------------------------------------------------
测试代码:
SuperClass clz = new SubClass();//多态
clz.doWork();//???输出什么结果.
前提:必须先存在多态情况
存在父类:SuperClass,子类:SubClass,方法:doWork.
--------------------------------------------------------------------
测试代码:
SuperClass clz = new SubClass();//多态
clz.doWork();//???输出什么结果.
情况1: doWork方法存在于SuperClass中,不存在于SubClass中.
//父类
class SupClass
{
public void doWork(){
System.out.println("SupClass.doWork");
}
}
//子类
class SubClass extends SupClass
{
}
//测试类
class TestDemo
{
public static void main(String[] args){
SupClass clz = new SubClass();
clz.doWork();
}
}
此时执行结果:
编译通过,
执行SuperClass的doWork方法.
应该先从SubClass类中去找doWork方法,找不到,再去父类SuperClass类中找.
情况2: doWork方法存在于SubClass中,不存在于SuperClass中.
//父类
class SupClass
{
}
//子类
class SubClass extends SupClass
{
public void doWork(){
System.out.println("SubClass.doWork");
}
}
//测试类
class TestDemo
{
public static void main(String[] args){
SupClass clz = new SubClass();
clz.doWork();
}
}
此时执行结果: 编译错误.因为编译时期,会去编译类型(SuperClass)中找是否有doWork方法:
找 到:编译通过.
找不到:编译报错.
情况3: doWork方法存在于SuperClass和SubClass中.
//父类
class SupClass
{
public void doWork(){
System.out.println("SupClass.doWork");
}
}
//子类
class SubClass extends SupClass
{
public void doWork(){
System.out.println("SubClass.doWork");
}
}
//测试类
class TestDemo
{
public static void main(String[] args){
SupClass clz = new SubClass();
clz.doWork();
}
}
此时执行结果: 编译通过,执行SubClass的doWork方法.
在运行时期,调用运行类型(SubClass)中的方法.
情况4: doWork方法存在于SuperClass和SubClass中,但是doWork是静态方法.
//父类
class SupClass
{
public static void doWork(){
System.out.println("SupClass.doWork");
}
}
//子类
class SubClass extends SupClass
{
public static void doWork(){
System.out.println("SubClass.doWork");
}
}
//测试类
class TestDemo
{
public static void main(String[] args){
SupClass clz = new SubClass();
clz.doWork();
}
}
此时执行结果: 编译通过,执行SuperClass的doWork方法.静态方法的调用只需要类即可.如果使用对象来调用静态方法,其实使用的是对象的编译类型来调用静态方法.和对象没 有关系.通过反编译工具可以查看结果为直接使用编译类型类名调用:SuperClass.doWork();