00:00
到目前为止,我们已经了解了skyla当中的面向对象三大特性,封装、继承、多肽,那这些内容我们会发现skyla跟Java基本上是类似的啊,Java是一门单继承多实现的语言,那skyla同样也是一门单继承多实现的语言,我们前面讲到继承的时候extend一个父类,那这个时候呢,只能有一个负类啊,就是不能到处认爹嘛啊,当然了,我们可以是负类,还有父类,那就相当于是祖孙三代一脉相承,这是可以的,我们发现这种表达呢,比较简洁,但是呢,有些场景可能就处理不了更复杂的情况了啊,那比方说像我们说这个学生,学生确实是一个人。继承父类person,这是代表了它的本质的,但是person这一个类里边呢,它能有的属性和方法可能就不是那么的多,因为有一些特别具体的东西,你不能统一的说每一个人都有,那比方说像我,我们一般情况下学生可能都是一个年轻人,但年轻人的很多特点,他的很多属性和方法就不一定是。
01:12
整个person这个类全能够占有的,全能够有的,那这种情况下,难道说我们把所有年轻人的那个特点就都得把这个在student里边就全部都要去实现一份吗?啊,那有可能我们另外再定义一个类啊,那有可能也需要有这些所有的年轻人的特点,那难道说我们就要把所有的代码都重复一份吗?啊,当然不需要,那这种情况下就是我们所说的要做多实现的表达了,在Java当中多实现的表达那就是使用接口interface,那就相当于我们可以一个类继承一个父类,这是表示它的本质。到底它本身是个什么样的东西类别,那么另外呢,还可以implement一些interface一些接口,那么这就表示我当前的这个类里边还可以有其他的一些特性啊,在Java里边有这样的一种定义,但是有些同学可能就发现了啊,所谓的接口interface这个概念呢,过于机器化了,就这种表达,我们感觉好像这就是一个像什么计算机接口啊,一个人机接口这样一种感觉,他就过分的工程化,其实对于人直观的理解来讲,并不是非常的友好。
02:31
那其实我们想要表达的是什么呢?不就是现在某一个类里边,呃,首先我们说这个类它可能有一种本质,那这个本质呢,我们就用继承关系,继承一个父类来体现,那至于其他他的其他的一些特征呢,你就干脆给它单独的定义一些特质,叠加进去不就完了吗?Skyla就用了这样的一种定义方式,所以呢,在skyla当中没有interface,没有接口的概念,而是用特制这个概念。
03:04
做了一个替代啊,那所以在SC当中,它就有一个关键字叫做treat啊,Treat就是英文里面的特征或者特质。类似于Java里边interface的使用。那在s scla的里边的tra呢,跟Java里面的接口还不太一样,我们知道在Java的interface里边,它是不能有私有的方法或者变量,都必须是public的,然后另外就是说所有的方法都是啊,没有方法体的,就相当于都是抽象的。而对于scla当中的treat呢,它是可以有抽象的属性和方法,也可以有具体的属性和方法,从这个意义上来讲的话,这就有一点像抽类了啊,前面我们讲过stla里边也有这个abstract class啊,啊,这点上的话,Treat跟abstract class就非常的类似了,那他们又有什么区别呢?简单来讲就是抽象类,我们一般情况还是用来体现它的特征的,是更加抽象的一个。
04:07
一个本质性的特征,这种情况我们用继承的关系,继承一个抽象类来做一个表达,而如果说是一些其他的附加的这些特征的话,那我们就可以把它提炼成一个treat啊,所以treat是更加灵活,更加方便的一种使用,大家可以认为是Java里边interface和抽象类的一个结合啊,那所以skyva当中呢,引入了tra,第一它可以替代Java里边的接口,第二呢,就是我们可以实现对单继承机制的补充。这就真正实现了单继承多实现啊,那当然如果要多实现的话,所谓的treat那就肯定是。不是简简单单只能引入一个,可以引入多个,那这种引入多个特征的特性呢,我们管它叫做混入mixing多个特特征特质,那接下来我们看一下声明特质和使用特质的一些具体的方法,那我们看一下特质的这个语法也非常的简洁,就是一个treat,然后后面加上特质名,后面画括号是treat的主体就可以了啊,所以整体来看的话,这跟abstract class抽象类啊,或者跟Java里边的interface定义其实是差不多的啊。那另外还有就是说,接下来如果我们想要去一个类啊,要去引入一些特质的时候,怎么样去引入呢?
05:33
同样也是用extend关键字啊,所以这样的话就避免了Java里面啊,我们继承的时候用extend,然后呃,如果要是实现接口的时候又要用implement,现在的话只有一个就是expense,所以如果说它本身没有负类的话。那就直接CE,大家知道CE就是扩,扩展的意思嘛,哎,所以就是把很多的特征特质扩展出来,引入进来,CE特质一,那如果要有多个呢,要混入怎么办呢?用with关键字做一个连接啊,所以就是特质1WITH特质2WITH特质三可以无限的扩充下去。
06:11
那假如说当前我还有一个继承关系,有父类,那又怎么办呢?啊,那也非常的简单,先写父类,就是class一个类名,然后extend后面是负类名称,接下来呢,所有的特质都是with后面跟着的啊,所以就是with特质一,With特质二位特质,特质三,无限的扩充下去。这就是特质基本使用的语法那类和特质的关系,它其实就可以类似于之前我们讲到的继承的关系,那从这个角度来讲的话,我们看这样的一个单继承多实现,似乎就跟多继承非常的接近了啊,当然我们一般情况还是说他跟庄老师一样,是单继承多实现的一个语法好,那然后接下来我们就在代码里边做一个具体的测试,我们看看到底应该怎么用。
07:05
还是新建一个scla的object,现在是S的13,我们主要测试的是treat,没办法简写出来,接下来呢,我们首先既然是有这样的一个treat引入啊,除了treat之外,我们还想测试一下,呃,还应该有父类,那我们就先定义这一堆这样的父子类型啊,我首先定义父类还是基于我们之前熟悉的这个所有的这个定义吧,定义一个person,当前是13,所以我们就定义一个PERSON13,呃,这里为了方便让大家看得清楚,我们就不用直接在主构造主构造器里边传参然后定义属性的方式了,我干脆直接在下边单独定义属性,而且直接把这一个估值写死,当前就是person,我们为了测试方便啊,然后接下来我们可以。
08:05
比方说定义一个age,就给一个变量可改啊,我们给一个18。然后接下来,呃,我们定义一个方法,比方说我们叫c hello,不要打印,输出一句话就可以了,可以是unit类型的返回值unit line啊,那接下来我们就是hello from,后面我们加上当前的内,就是对于这个父类的基本的定义,有两个属性,一个方法,然后接下来啊,那子类如果要写的话,就应该是as student13 extend,一个PERSON13,那当然了,现在我们子类里边应该还可以定义。实现吧,可以定义特征是,那现在我们就在前面再去定义一个特质特征it用这个关键字名,前面不是说了吗?呃,学生除了他本质是一个人之外,他还是一个啊,一个年轻人,他有年轻的特质,所以我们单独定义一个年轻叫做要。
09:24
这是一个特质,那么年轻这个特质里边又有什么样的属性和方法呢?哎,就是这里边我们可以看到啊,里边可以定义抽象和非抽象的属性和方法,所以我们声明抽象和非抽象属性,比方说我这里边可以定义一个。In里边不负出值啊,大家知道就是当前这个样,这个特质里边,他的这个年龄可能就会跟person里边略有不同,对吧?啊,那当然了,就是前面这个person可能也不需要直接就给一个18啊,这里边可能是一个更加宽泛的值,那样的话可能这个。
10:11
具体的限制就要比person要严格很多啊,接下来我们再看,呃样可能也可以给一个name啊,我们直接把它定义出来吧。这个name我们还是一个初值,有一个具体的实现,就是要那接下来我们再去证明。抽象和非抽象方法TF,那首先我们可能说这个年轻人嘛,年轻人比较有活力啊,应该可以有一个方法叫做play,可去去嗨,去玩耍,这个我们也不需要有返回值打印一句话了,我么说,呃,Young is可就是一个具体的方法,那当然了还可以定义啊,抽象的方法,比方说年轻人,年轻人还可以约会嘛,这个我们不做具体的实现,用在这里就是一个抽象的方法啊。所以大家看整体来讲这个使用定义的过程啊,跟前面我们讲的抽象类其实是非常的相似。
11:27
那只不过用起来可能就更灵活嘛,因为我们可以可以有这个多实现有多个。It可以做这样的一个使用啊,那接下来要定义的话,首先继承了自己的父类,接下来那就是with一个特征,当的特征,年轻人的特征,既然译成了这个特征,那就得把里边所有的抽象方法和属性必须要实现才行啊啊,当然这里边我们还可以去重写一些其他的方法,因为这里大家会发现啊,就当前在这个student里边,呃,首先我们先把对应的这个抽象属性和方法都都写出来吧,啊呃,首先这里面有一个。
12:10
大家看到有一个age,这是一个抽象的属性,而且我们会发现啊,这里面其实关键在哪里呢?有同学可能会会想,我们先把这个。就是这里边还有这个age name2个属性在父类里边也继承了,有,那这里面就涉及到一个问题啊,就是说我这里边的name,它也有一个实现样,父类里边是一个person,那当前继承了之后,到底应该算谁的呢?那我们等一下先看它,我们先把定的那个抽象方法先定义出来,大家看这里边我就需要去override前的这个这个方法对吧?啊,那当然了,当前这个dating方法我们不行。不写override,直接去实现也是可以的,不像类的这个实现是一样的啊,那这里边我们干脆就直接写一句。
13:02
从前是一个student啊,Student is,那这里面可能还涉及到一个就是student name到底是什么?那我可以直接Dollar name放在这。就找我知道现在应该有一个name放在这儿,那大家可以猜测一下当前的name应该是谁啊啊,那另外除了这个之外呢,我也可以定义自己,有的我们在这儿先写一下,这是直线抽象方法,然后另外我们还可以实现第一个学生特有的方法,比方说学生还可以,学生嘛要学习study。同样,Unit我们直接打印,一句话,好,目前我们还是啊,那就student谁name放在这儿,Is study。啊,这就是简单的一些定义啊,对于父类已经继承的方法,当然我们也可以去重写,重写复类方法override啊,那大家看到其实与它既成自样的特征里面的方法也可以重写,对吧?啊,Play可以重写,比方说这个say hello也可以重写啊,那我们这里面就直接。
14:23
既然这里有super啊,我们就干脆把这个super也调一下吧,先调一下super.a hello,然后接下来我们再line这里边hello from后面啊,我们可以加上这个student。啊,这样的话就是把之前所有的方法我们都做一做了一个具体的实现啊,那首先我们这里可以先在main方法里边做一个测试,看看当前输出的应该是什么,另一个student,用一个当前的STUDENT13。
15:06
需要有任何的参数传入啊,直接就可以得到啊,那么接下来student首先我们调一下c hello,那大家想一下当前这个c hello应该调的是谁呢?啊,这没有问题,肯定是他已经重写了嘛,那调用的肯定是自己的c hello方法。我们这里并没有测这个多肽相关的内容啊,前知道如果要是不定义它的类型的话,默认其实就是自动推断,推断出来就是STUDENT13类型,好,接下来那我们就可以调用它的study方法,还有eighteen方法,当然了它还有一个配方法啊,接下来我们来看一下除数的结果是什么。这里大家看到直接在这里运行的时候,尽管idea没有报错,直接运行这里报错。这里什么意思呢啊,大家其实就看到它主要的问题就在于。
16:03
我们现在不知道name到底是什么,因为他继承了父类PERSON13里边的name有一个具体的实现,叫person。同时呢,哎,它又相当于也是继承啊,有一个特质叫样,那么继承来呢,有一个属性同样是叫做name,而且也有一个值叫样,那这里边就完全不知道该怎么做了,到底当前我是样呢,还是叫做person呢?哎,那你必须要有一个定义才行,所以大家看到这里就必须得就是当前的这个属性相当于冲突了,大家看到一个conflict conflicting member啊,那这样的话我们需要重写冲突的主线,所以这里边我们就得override,大家看到override一个内啊,比方说当前我就直接把重写的话,那当然就是以自己的为准了。
17:02
Or一个student的话就可以做到这一点了,我们现在可以运行一下。哦,大家可以看到当前hello from student,首先这里调用的这个c hello。我们首先是掉了它的负类的c hello方法,所以在这儿显然是要有一个hello from的,那这里hello from,我们看到负类它的这个呃,就是person,这里边调的时候是hello from加上name,那这里的name是person吗?大家注意不是我们当前在SC里边所有的当前的这个属性啊,调的都是自身的这个属性,对吧?啊,就是相当于是一个动态绑定吧,所有针对的当前这个name已经都变成了student。然后另外呢,下面又掉了自己输出的这一句,Hello from student加上name,当然name还是student了,所以就变成了student student啊,那接下来同样也是student student啊,Is studying is dating,那这里注意最后我们还调了一个play a方法呢,因为在student里边没有做重写,所以调用的就只有young里边的对应的这样一个方法,那调用这个young里边方法,当然就输出的是young people is playing。
18:18
这就是关于我们当前的这种用法,当然在这里大家会看到我们也可以做一个。更改一下啊,我们可以说哦,Young people。里边后面我们加上Dollar。我们自然会想到,如果加上name的话,那相当于还是以当前的name为准,不会是改成young,所以大家看到是young people student is playing。这就是关于我们当前啊。特征特质treat的主要的用法。
我来说两句