00:00
完了继承,那接下来我们再来说一说多肽,关于多肽,可能很多同学会觉得这是面向对象里边比较难理解的一个概念,那什么是多肽呢?呃,简单来讲就是多种状态,那在官方的定义里边,大家会看到他说的是一种接口,可以有多种不同的实现方式啊,那这种特性就叫做多肽,这个看起来还是会比较抽象啊,我们还是结合具体的例子来给大家分析一下,到底怎么样去实现这个多肽,我们需要的这个需求到底是什么样的,那比方说像现在我们已经定义了一个父类person,然后定义了一个子类叫student,那那大家可能会知道当前我们这个方法里边啊,如果要是。有那个print infer打印信息的方法嘛,我们定义了STUDENT1STUDENT2,这里我们没有指定它的类型,那我们其实知道编译器自动推断的话,你既然new的是STUDENT7的啊,对应的这个对象,那当然当前的类型就是。
01:03
2STUDENT7不会推断成它的负类啊,这个是肯定没有问题的,所以接下来如果我们要去直接调它的这个打印信息方法的话,那这个其实毫无疑问,自然调用的打印出来都是student的相关信息,调的是子类的方法,没有任何问题啊啊,那自然我们就想到了具体实践的过程当中,很可能这个person类里边。他的子类不止是学生一个呀,有可能我们还还有可能有一个比方说TEACHER1个子类,我们把teacher这个子类也写出来,Extend person,那大家会想到有这样的一个此类的话,里边可能也有一个打印信息的方法,那当然当前我们就没有对应的那些信息了啊,就直接输出一个teacher就好了,那现在我们定义了这样的两种不同的类型,接下来呢,我们自然知道啊,如果。我明确的知道,当前就是一个teacher的话,那自然打印到它的printer方法,那调的应该也是子类的打印信息的方法,输出的是teacher,哎,这是我们当前能够想到的啊,这是继承关系决定的,那现在的问题在于,假如说现在我要定义另外一个函数。
02:24
当前这个函数呢,我们来看一下啊,比方说我们当前就是一个叫person iner的一个函数,那当前。不然我就不知道要传入一个什么样的person进来了啊,那我就直接写一个。当前的一个person,它的类型是PERSON7另来,然后接下来呢,呃,我也不需要有任何的返回,因为是打印信息嘛,直接来一行,诶大家会想到我这里边需要去做一个print line打印信息,这里边其实没有必要再去单独实现了,因为person我们本身就有它的print infer方法呀,哎,所以在这里我直接可以啊person的print infer方法,这里面大家就会想到有一个问题啊,目前我这个person infer。
03:11
如果要在外部调用的时候,我可以直接传person,这是没有问题的啊啊,那当前打印的当然就是person对应的这些信息打印出来,那假如说我当前是一个student呢。诶,那家想我也可以,因为他student也是person嘛,所以其实也可以传一个值,然后付给当前person的应用,把这个参数,其实里边传进来的是一个student的对象实例,这也是可以的,那这里边打印的时候,我们应该打印出谁的信息呢?哎,我们当前要解决的就是这样一个问题了,自然我们就想到了,应该是还是去调用这个子类的print info方法打印出来应该是更具体的student信息,这是我们想要的。那大家就会想到,呃,如果要是这样做的话,那我一开始编译器在看到这样一个方法调用的时候,我就不能直接去调PERSON7的printer方法了啊,就不能把这个直接就绑定死了,所以大家会发现啊,在面向对象的语言里边都有这样的一个特性,就是所谓的动态绑定,就如果在编译期间我们就直接把它绑定死的话,这是静态绑定。那我们现在要的是什么呢?是要编译期间不直接绑定方法,而是在运行时才去判断当前的这个person,诶,这个到底是谁的实例呢?如果是student,那我这里就调用student的print in for方法,如果是person,那你就调用person的方法,那如果是teacher,那就调用teacher的方法。所以这才是我们所谓的多态,它主要就是通过动态绑定方法运行时采取绑定方法来实现的。
04:55
哎,那我们现在来测试看一看啊,前如果我们要直接调这个person info前边的。
05:03
Student'一做一个进来啊,我们看一下,然后再调person infer,把前面的teacher进来看一下再了,另外我们也可以比方说这里我们再单独的就定义一个person又一个。这样的话,下边我们还同样可以调用person info去看一下这个person的信息,打印出来又是什么啊?前面我们加一行界线。让大家看得更清晰一些。运行一下。我们可以很明显的看到下边这里,其实student传入student,这里边输出的就是student的信息传入teacher。就是T的信息传入person,就是person的信息啊,所以现在我们这里边是用了一个负类的类型来做这个参数的接收,呃,那大家可以想象得到,如果我们是用一个接口的话,显然也可以做到类似的效果,对吧?所以我们在定义多态的时候,指的就是要把一个子类或者是实现类的对象实例传给一个父类或者是接口的,呃,一个引用,这样的话我们就可以实现同一接口有多种不同的状态,多种不同的实现。
06:25
这就是所谓的多态啊,那这里边又提到另外一个重要的概念,就是动态绑定,动态绑定其实就是实现多态的具体的一个手段,呃,所以往往这两者啊,我们都是把它们放在一起来介绍的啊,就是动态绑定和多态大家可以认为是一回事,那这里边呢,就必须提到skyla跟Java当中的一个区别啊,那关于这个动态绑定我们知道啊,在Java里边。它也有这样的动态绑定,但是呢,动态绑定的只有方法,诶,也就是说我们调用这一个对象的方法的时候,我可以在运行时才判断当前对象实例到底是谁,而对于当前对象的属性,它不是动态绑定的。
07:12
啊,关于这个我们还是专门写一个测试啊,我们这里不是skyla的。我们要创建一个Java的class,做一个具体的测试,我们来看一看在Java当中所谓的这个动态绑定有没有局限性,那那我们S。I。动态绑定试一下,然后接下来我们把main方法写出来之后,呃,首先还是要先去定义对应的父类和子类啊,那这里边我们干脆就还是它定义出来,定义一个,呃,这里边我们就为了测试啊,给一个属性和name,目前我直接给一个默认值就叫person,然后下边呢,呃,再单独的定义一个方法,我们叫哈,打一个招呼。
08:15
里边直接做一个突出一句话啊,我们就直接,然后接下来我们再定义一个子类,因为我们外面已经有student类了啊,我们这里干脆定义一个worker吧,Extend person,同样接下来我们应该有一个name属性,里边就叫worker,然后里边有一个hello,我们这个叫hello worker,后面我们就可以具体来做一个测试了,那首先我们定义一个worker,你有一个worker,呃,把这个创建出来之后,呃,首先我们可以直接去访问当前这个worker的属性内,然后我们可以调用当前这个worker的魔法哈,啊,那大大家知道这个肯定都是没有任何问题的啊,肯定都可以访问到,输出的肯定都是worker相关的这个信息,那当然了,对于这个worker。
09:15
而言,我们也可以单独的再给它定义一个。一个呃,自己的一个方法啊,比方说我们叫hi hi worker这里也可以直接去做一个用worker点。肯定都是没有问题的,现在的关键问题在于我们要测一下多肽,多肽的用法,因为我们也已经说了,关键就在于要把一个。子类的对象不给。不给啊,负类的一个类型对吧,负类的引用,所以这里边我们可以定义一个。呃,我们就把这个叫做person吧,就一个worker给给到他,然后接下来我们这里边呢,直接去访问person.name然后看看是什么,然后去调用person.hello person.hi啊,当然了,大家知道当前person里边并没有hi方法,所以这里边你直接调这个害肯定是不行的,对吧?哎,这个是error,没有这个法,那关键就在于当边这个person.name person.hello调这个hello方法输出的到底是什么呢?
10:28
哎,我们来直接运行一下,为了看更清楚一点,我们上面还是来一个分割线,再来我们运行看看效果怎么样。大家看到这里边person.name输出的是person,而下边person.hello调用方法的时候输出的是hello worker,下面这个hello worker,其实我们现在已经理解了,这就是动态嘛,呃,这就是动态绑定嘛,这就是我们所说的多态的特性,就是在运行时的时候才去判断当前的这个person,具体的对象实例到底是什么,我们发现它是worker,所以它调的其实是worker的点hello方法,但是上面的这个person.name呢?啊,大家发现了它并不是动态绑定的,在Java里边属性是静态绑定的,也就是在编译期直接绑,绑定死了,那他看的就是目前的类型是person,所以person.name当然就是person了,所以这个大家一定要注意一下,静态绑定行,而下边无法调用,那是动态绑定。
11:42
是Java里边的特点,那大家就会发现这种用法的话,显然就容易出现混淆啊,如果说我们想要使用这个多肽的话,我自然是想当前是worker的话,那属性和方法都应该调worker的才对呀。哎,所以基于这样的想法,在scla当中就对于这一个动多态全部把它实现成了动态绑定,就不管是属性还是方法全部都是动态绑定。
12:09
啊,所以接下来与之对应的我们还是先给大家专门在创建一个scla的object,把这个专门再说一下啊,接下来就是TEST08,我们要测的是动态绑定dynamic这方法写出来啊,那同样这边我们还是要有这个对应的父子类型啊,这个我们快速写一下,它既然是零八啊,我现在就是PERSON8里面的内容跟前面我们在Java代码里面定义的非常类似啊,Name直接给一个,然后接下来我们EF一个hello方法。回执有类型里面我们直接print line打印一句hello,就是互类,然后接下来我们再定义一个子类,这个我们干脆定义成student吧,STUDENT8 extend person8,然后同样里边我们也是要定义这些,大家需要注意的是Java Java里边略有不同,Java里边的话,那是我们直接在子类里边啊,对应的属性和方法名称一样,相当于就直接重写了啊,相当于覆盖了这个负类,负类里边的方法了。而在。
13:35
SC里边呢,如果是相同的。属性名称和方法名称的话,在此类里边如果要覆盖啊,必须加override关键字,大家看加上override的话的话,就明确表示要去重写啊,这样的话大家其实看到尽管多写了一个关键字,但其实表达的含义更加明确了,这样一眼就能看得出来,这个属性是本来继承自父类,但是这里我又把它做了一个重写啊,所以接下来这里我们叫做student,然后同样下边的这个hello方法,那自然也要override啊,Hello下面就是hello student下来我们同样在上边可以做一个具体的测试啊,跟Java那边的测试的流程一样,我们可以定义一个student'。
14:25
啊,那么它的类型我们要直接定义成八,然后去new一个student吧,下来我们直接printline当前student name,另外呢,报一下student的hello方法,现在我们运行一下,看看效果怎么样。大家看到输出的就全部都是student了啊,所以这个大家要注意一下啊,就是在Java当中属性是静态绑定的,而在skyla当中呢,属性和方法都是动态绑定的,关于多态这一部分,就是skyla比Java做的更加的特彻底,而且完全没有混淆,全部动态绑定,我们需要把这个深入的理解一下。
我来说两句