美文网首页
说说 Java 多态那些事儿~

说说 Java 多态那些事儿~

作者: Vector_Wan | 来源:发表于2019-10-21 21:59 被阅读0次

    都说面向对象有三大特性:封装、继承、多态。前两个在 Python 中很常见,也一直再用,就不特别整理了。但是在多态这个地方就跟 Java 有点不同。我们仔细研究一下看看。

    多态 Polymorphism 分为两种,编译时多态,就是函数重载啦(overload)注意与下面的 override 区别一下。还有一个是运行时多态,我们今天主要研究研究这个。
    要想理解好多态,我们得先知道 emmm 很多事情,,,,让我一件一件来说。

    1. 强制类型转换

    首先就是 Java 中的类型转换,其实这个没啥可说的,只是需要注意一件事情,类型转换数据本身没有变化。比如下面这段代码,变量 a 一直都是一个 char 类型的变量,只是将它暂时作为 int 型的变量使用一下。

    class Hello{
        public static void main(String [] args){
            char a = 'a';
            int num = a;
            System.out.print(num);
        }
    }
    

    2. 覆写

    在继承关系中,子类如果定义了一个与父类方法完全相同(函数名、参数列表、返回值类型)的方法,被称为覆写(Override)。
    注意与重载(Overload)进行区分,重载是指一个类中的两个方法函数名和返回值一样,但是参数列表不同。
    另外:方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。在Java程序中,出现这种情况,编译器会报错。

    3. 程序绑定

    绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。分为静态绑定和动态绑定。
    直接举个动态绑定的例子吧,比如说有人结婚邀请你家去参加婚礼,但是具体谁去还不一定,有可能是你妈妈,有可能是你,有可能是你妹妹,这要看当时你们家谁有空(说不定后来你们家来了个亲戚,婚礼的时候你们都没空,就让他去了)。要是静态绑定呢,指定是谁,就必须是谁,而且编译的时候这个人必须已经存在。

    比如我对于静态绑定(像 C 语言),指定使用哪个对象就是哪个对象,指定哪个属性,这个属性就必须存在。
    对于动态绑定(比如 Python 支持的动态绑定),调用一个对象的方法,如果这个方法里使用到了一个属性,但是我的这个类还没有这个属性,它是在运行过程中产生的。也不用管这个属性属于哪个对象,这个属性是啥时候才有的,只要在我执行这个方法的时候这个对象里面有我想要的属性就 ok 。
    Java 是一个比较折衷的语言,java 当中的方法只有 final,static,private 和构造方法是静态绑定,剩下的都是动态绑定。

    4. 上转型对象

    然后就是上转型对象,简单点来说,上转型对象就是对象级别的强制类型转换。这是一个 引用变量的声明类型与其实际类型不符 的例子。

    将子类对象赋值给一个父类的引用类型变量,(将子类理解为一个父类使用,没有转化!!)这个父类引用所指向的对象就叫上转型对象。

    上转型对象的特点:

    • 父类引用不能访问子类新增的成员(属性和方法);
    • 父类引用访问父类中被隐藏属性时访问的是子类继承(父类)的属性。
    • 父类引用调用被子类覆写的父类方法时调用的是子类覆写后的方法
      (有没有想起来 C++ 中的虚函数)

    上转型对象就是动态绑定的一个体现,比如在使用父类引用调用被子类重写的方法的时候,我不去管这个对象是哪个类的,只要里面有我要的方法就行,自然这样调用的就是被子类重写的方法。
    我们先来看一个例子:

    public class Area{
        public static void main(String[] args){
            Animal dog1 = new Dog();
            dog1.run();
            System.out.println(dog1.age);
        }
    }
    
    class Animal{
        public int age = 0;
        public void run(){
            System.out.println("动物跑。。。");
        }
    }
    
    class Dog extends Animal{
        public int age = 100;
        @Override
        public void run(){
            System.out.println("狗跑。。。");
        }
    }
    ## 狗跑。。。
    ## 0
    

    注意这个结果,方法可以被覆写,所以使用的是覆写之后的方法,但是属性没有覆写这一说,所以使用的就还是父类继承下来的属性。
    还有在子类里面可以使用装饰器 @Override 标识一个覆写函数,这样解释器就可以帮我们检查是否真的是覆写。

    不同的子类覆写的方式也不同,这样调用相同的父类方法,对于不同的子类,所得到的结果就不同,这就是多态的效果。

    5. 多态

    正如上文所说,多态就是 同样的行为(同一段代码)作用于不同对象时产生不同的效果。

    多态想要解决的问题主要是:设计和实现的分离,这样修改设计,修改实现都非常容易。另外这样写的话代码量也会比较少,也比较容易阅读。
    比如看下面这个代码:

    public class TestPolymorphism{
        
        public static void main(String [] args){
            Dog dog = new Dog();
            Cat cat = new Cat();
            Bird bird = new Bird();
            dog.saySomething();
            cat.saySomething();
            bird.saySomething();
        }
    }
    
    
    class Dog{
        public void saySomething(){
            System.out.println("汪汪汪......");    
        }   
    }
    
    class Cat{
        public void saySomething(){
            System.out.println("喵喵喵......");    
        }   
    }
    
    class Bird{
        public void saySomething(){
            System.out.println("啾啾啾......");    
        }   
    }
    

    这个例子太经典了....
    下看一下使用多态的实现

    class TestPolymorphism{
        public static void animalSaySomthing(Animal an){
            an.saySomething();
        }
    
        public static void main(String [] args){
            Dog dog = new Dog();
            Cat cat = new Cat();
            Bird bird = new Bird();
            animalSaySomthing(dog);
            animalSaySomthing(cat);
            animalSaySomthing(bird);
        }
    }
    
    class Animal{
        public void saySomething(){}
    }
    
    
    class Dog extends Animal{
        public void saySomething(){
            System.out.println("汪汪汪......");
        }
    }
    
    class Cat extends Animal{
        public void saySomething(){
            System.out.println("喵喵喵......");
        }
    }
    
    class Bird extends Animal{
        public void saySomething(){
            System.out.println("啾啾啾......");
        }
    }
    

    当我们不光想要动物叫还想让他们做其他事情的时候,多态的好处就显现出来了,比如说我还想增加跑,吃,上树的方法,按照第一个的话那就需要为每一个都增加一个方法,然后每一个调用一遍,但是使用多态的话我们只需要在Animal 类中增加相应的接口,然后在子类中实现它。

    额,,看到这里你一定会说这不是更麻烦了嘛,,,emmm,对于这个例子来说确实是这样,在实际生产环境中,也就是对于大型程序,多态主要是用在接口中,那个时候才能真正体现 Polymorphism 的作用。

    相关文章

      网友评论

          本文标题:说说 Java 多态那些事儿~

          本文链接:https://www.haomeiwen.com/subject/dxbauctx.html