JAVA中面向对象-对象的多态 与 多态类型判断 以及 多态成员的特点

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_42947972/article/details/102511471

对象的多态

例子:

class 动物
{}
classextends 动物
{}
classextends 动物
{}

猫 x = new();
动物 x = new(); 

一般一个对象两种形态,我们就可以认为是多态了
例如:动物 x = new 猫();

 猫这类事物即具备猫的形态,又具备着动物的形态.
    这就是对象多态性

简单说:就是一个对象对应着不同类型

左边是动物,右边是猫,两种形态,我们就可以说它是多态的

多态在代码的体现:

		父类或者接口的引用指向其子类的对象
多态的好处:
      提高了代码的扩展性.前期定义的代码可以使用后期的内容

多态的弊端:
      前期定义的内容不能使用(调用)后期子类的特有内容.

多态的前提:
      1.必须有关系,继承,实现
      2.要有覆盖

例子:

abstract class Animal
{
    abstract void egt();    //吃东西
}

class Dog extends Animal
{
    void egt()
    {
        System.out.println("啃骨头");
    }
    void lookHome()
    {
        System.out.println("看家");
    }
}

class Cat extends Animal
{
    void egt()
    {
        System.out.println("吃鱼");
    }
    void catchMouse()
    {
        System.out.println("抓老鼠");
    }
}

public class DuoTaiDemo {
    public static void main(String[] args){

        Animal a = new Cat(); 
        //自动类型提升,猫对象提升了动物类型.但是特有功能无法访问.
                              //作用就是限制对特有功能的访问.
                              //专业讲:向上转型.
        a.egt();
         //c.catchMouse();//报错
		 method(a);//这样可以提高代码的复用性,如果继续new别的对象的时候,也能用
       
        
        //如果还想用具体动物猫的特有功能.
        //你可以讲该对象进行向下转型.
        Cat c = (Cat)a;//向下转型是为了使用子类中的特有方法.
        c.egt();
        method(c);//这样可以提高代码的复用性,如果继续new别的对象的时候,也能用
        c.catchMouse();//猫的特有功能(方法)

        //注意: 对于转型, 自始至终都是子类对象在做类型的变化.
        //Animal a1 = new Dog();  
        //Cat c1 = (Cat)a1;
        //报错: ClassCastException 类型转换异常
        //这里是Dog类型向上转型,然后把它向下转型为Cat...
    }
    public static void method(Animal a) //Animal a = new 不同子类对象()
    {
        a.egt();
    }
}

.
.
.

多态类型判断

关键字: instanceof

例子:

 public static void method(Animal a) //Animal a = new 不同子类对象()
    {
        a.egt();
        if(a instanceof Cat)   
        {                       
            Cat b = (Cat)a;
            b.catchMouse();
        }
        else if(a instanceof Dog)
        {
            Dog b = (Dog)a;
            b.lookHome();
        }
        //这样挨个判断的几乎没有...
    }

关键字instanceof:

		用于判断对象的具体类型.只能用于引用数据类型判断
		通常在向下转型前用于健壮性的判断.

一般在我们转型的时候判断,让它给我们反馈.
.
.
.

扫描二维码关注公众号,回复: 7570241 查看本文章

多态成员的特点

1.成员变量

例子:

class Fu
{
    int num = 3;
}

class Zi extends Fu
{
    int num = 4;
}

public class Demo {
    public static void main(String[] args){
        Fu f = new Zi();
        System.out.println(f.num);
    }
}

结果:
在这里插入图片描述
因为Zi类,向上转型为Fi类
所有f.num就是调用父类的num
不过一般开发不这样弄,因为都已经有了,直接调用就完事了…
面试可能会问到

.
.
.

2.成员函数

例子:

class Fu
{
    void show()
    {
        System.out.println("fu show");
    }
}

class Zi extends Fu
{
    void show()
    {
        System.out.println("zi show");
    }
}

public class Demo{
    public static void main(String[] args){
        Fu f = new Zi();
        f.show();
    }
}

结果:
在这里插入图片描述
为什么会输出zi show

图解:在这里插入图片描述
刚开始主函数main进栈
在这里插入图片描述
然后f new Zi()
Zi类继承了Fu类,他们两个一起进入了方法区
在这里插入图片描述
接着创建了一个对象,并分配了地址
在这里插入图片描述
再然后把地址给到变量f, f指向对象在堆内存的地址
在这里插入图片描述
接着f调用了show()方法
这时就会先在Zi类show()方法,发现有,就输出了—zi show
假设Zi类没有show()方法,那么就是通过super进入Fu里面找show()方法

Fu还没有的话,就直接报错了
.
.
.

3.静态函数

例子:

class Fu
{
    static void method()
    {
        System.out.println("fu static method");
    }
}

class Zi extends Fu
{
    static void method()
    {
        System.out.println("zi static method");
    }
}

public class Demo{
    public static void main(String[] args){
        Fu f = new Zi();
        f.method();
    }
}

结果:
在这里插入图片描述
为什么会输出:zi static method
图解:
刚开始与前面差不多
在这里插入图片描述
在这里插入图片描述
不同的是这里的静态方法是加载进静态的方法区
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
全部好了之后执行下面的语句调用了静态方法f.method();
这时因为Zi类向上转型,于是变成了Fu类的.
于是就调用了Fu类的静态方法了,输出:fu static metheod

如果是 Zi f = new Zi();
那么执行静态方法f.method();的时候,就输出:zi static metheod

其实如果我们调用静态方法时,不需要用到对象时,可以直接通过类进行调用进行了
例如:

Fu.method();
Zi.method();

.
.
.
通过上面三个例子我们可以得出多态成员的特点

1.成员变量
        编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败.
        运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量.
        简单说:编译和运行都参考等号的左边.
        作为了解就行了

    2.成员函数(非静态)
        编译时:参考引用型变量所属的类中的是否有调用的成员函数.有,编译通过, 没有, 编译失败.
        运行时:参考的是对象所属的类中是否有调用的函数.
        简单说:编译看左边,运行看右边

    3.静态函数
         编译时:参考引用型变量所属的类中的是否有调用的静态方法.
         运行时:参考引用型变量所属的类中的是否有调用的静态方法.
         简单说:编译和运行都看左边
         其实对于静态方法,是不需要对象的,直接用类名调用即可.

猜你喜欢

转载自blog.csdn.net/weixin_42947972/article/details/102511471