‫欢迎回来｡
‫在本视频中, 我们将介绍抽象类, 因此我们将创建一组新类｡
‫理解类的概念以及继承和多态性是很重要的, 因为我们将在此基础上进行构建｡
‫我们首先要创建一个新类｡
‫因此, 让我们创建一个新类｡
‫这里我们转到Project Add类, 我将创建一个形状类, 这将是形状CSS｡
‫现在, 我们要创建一个类, 但不想创建任何对象,
‫所以我们不会不想实例化形状.
‫我们要实例化的对象是形状的类型, 而不是形状本身｡
‫例如, 一个形状是立方体或者一个形状是球体｡
‫我用的是3D图形, 对吧？
‫三维形状｡
‫我们要创建继承自shape的类, 但我们要确保shape是一个真正的抽象类,
‫这意味着我们不能创建它的对象, 但我们会使用它的系统,
‫方法和属性｡
‫那么我们开始吧｡
‫首先, 让我们把这个形状抽象化｡
‫为了做到这一点, 我们可以使用关键字abstract｡
‫所以现在它是一个抽象类｡
‫现在让我们继续看我们的程序, 看看它是一个真正的抽象类｡
‫让我们创建一个形状｡
‫形状一等于新形状｡
‫所以当我们尝试这样做的时候, 你可以看到不能创建一个抽象类或者接口形状的实例｡
‫因为我们的形状是一个抽象类, 我们不能创建它的对象, 所以我们不能实例化它｡
‫这一点很重要｡
‫好吧, 我会的
‫现在我们需要一个属性, 我将创建名为name得属性.
‫所以这个形状需要一个名字, 我们有一个getter, 等等｡ 为了创建这个, 我只是使用前道具, 然后双击,
‫以创建一个新的属性｡
‫我们在其他视频中也看到过｡
‫现在我想有一个方法, 我想使用的方法将是一个虚拟方法｡
‫虚拟无效获取信息｡
‫您在这里看到的这个虚拟键盘, 是用来修改基底类别中宣告的方法属性索引子或事件,
‫并允许在衍生类别中覆写｡
‫因此, 这允许我们在驱动类中覆盖get info方法｡
‫好吧, 我会的
‫这就是这个虚拟关键词背后的想法｡
‫我们在这里添加一条语句｡
‫因此, 请参见w双制表符, 以获得控制权行｡
‫这里我只想写这样的东西｡
‫这是一个然后是形状的名称｡
‫所以这是一个名字｡
‫这背后的想法是, 我想有一个新的行, 然后我想有这个语句｡
‫这是一个然后是形状的名称, 因为无论何时我们创建一个形状, 我们都可以设置它的名称｡
‫所以我们有一个虚拟的空白｡
‫现在, 我们还可以添加一个抽象方法｡
‫现在让我们来做一个抽象的双卷｡
‫所以我想计算的是一个形状的体积｡
‫现在, 在这里, 我将不实现这个方法｡
‫这是一个重要的区别｡
‫我不打算在这里实现它｡
‫我只想说, 好的, 每当一个类想从我这里继承, 它需要实现一个volume方法的功能｡
‫好吧, 我会的
‫当然, 我们可以称之为, 计算体积之类的东西, 但我只称之为体积｡
‫好吧, 我会的
‫现在我们已经准备好了形状类, 可以保存它并创建一个新类｡
‫我接下来要创建的类是立方体类｡
‫我将创建一个立方体, 它是一个3D形状｡
‫所以现在我的立方体将继承形状｡
‫现在, 如果我这样做, 你可以看到我得到一个错误在这里｡
‫它表示Cube不执行继承的抽象成员形体体积｡
‫因此, 请展示解决此问题潜力
‫好了, 实现抽象类｡
‫如果我这样做, 你可以看到它用一个override语句实现了这个volume方法｡
‫所以它说它覆盖了形状中定义的任何东西｡
‫因为shape是一个抽象类而这个方法也是抽象的｡
‫正如您所看到的, 没有方法体｡
‫它实际上只是方法的声明｡
‫现在, 我们可以继续进行, 当然也可以实现一些东西｡
‫你可以看到我们在这里抛出了一个错误, 未实现的异常｡
‫我们当然要在这里实现一些东西｡
‫因此, 让我们在立方体类中实现一个体积计算｡
‫为了计算它, 我们需要一个长度的属性｡
‫我将在这里创建一个名为length的新属性, 并添加一个构造函数.
‫所以无论何时我想创建一个立方体, 我都需要传递一个长度｡
‫所以这就是我要说的｡
‫我还想加一个名字
‫正如您所看到, 我们在这里使用继承是因为名称不是在立方体中定义, 而是在形状中定义
‫所以我可以在这里设置变量名, 然后把长度设置为传递给我的长度.
‫因此, 属性length的长度会与我们建立型别物件时所传递的长度相同｡
‫问：这就是这个变量背后的想法｡
‫接下来我们可以实现这个volume方法, 我们可以简单地返回一些东西｡
‫所以它需要返回一个双精度值, 对吗？
‫所以我们需要返回基于double的值｡
‫为了计算一个立方体的体积, 我用了一个边长相等的立方体｡
‫所以我只说长度是3的幂｡
‫所以数学, 纸浆, 长度三, 这意味着它要计算长度, 乘以长度, 乘以长度｡
‫这就是我们的体积, 它会返回这个值｡
‫现在, 我们可以继续, 我们也可以实现这个方法, 称为获取信息｡
‫我要做的就是复制它, 我现在不使用virtual关键字,
‫而是使用override关键字, 因为我现在要在这里重写父进程的get info方法.
‫如果我这样做的话, 我还可以从基类中调用get info方法, 也就是说, 在这个例子中, 它也会从shape.
‫CSS中调用get info.
‫所以它会在这里调用这个方法｡
‫也就是说, 它将执行这段代码, 然后它将执行我们在它的底部添加的任何代码｡
‫所以我在这里加一点文字说明立方体的长度, 然后我在这里传递长度.
‫当然, 长度, 我也可以计算体积, 但我会留给你们｡
‫所以如果你想做的话, 请随意｡
‫好吧, 我会的
‫这就是我们能做到的｡
‫继续创建一个类, 它将继承自另一个抽象类｡
‫现在, 作为对你们的一个小挑战, 我将暂停视频一次, 你们应该从一个挑战开始｡
‫所以现在的想法是创建另一个形状, 这是另一个从形状继承的类, 形状应该是一个球体｡
‫现在, 实现与此处所示的Sphere相同类型的功能｡
‫好吧, 我会的
‫祝你好运
‫发布视频并尝试这样做｡
‫好吧, 我会的
‫所以我希望你试过了｡
‫我将在这里创建一个新类, 并将其命名为sphere. CSS.
‫这个类应该继承自shape｡
‫当然, 我需要实现我的抽象类, 这意味着我需要实现这个volume方法｡
‫在这里, 我可以再次计算, 或者有一个性质, 但这次一个有用的性质不是长度,
‫而是半径, 因为我们计算球体的体积和计算立方体的体积是不同的｡
‫我们没有在形状上做, 因为形状本身不可能有体积, 对吗？
‫如果它不定义为Y形, 我们就无法计算它的体积, 因为我们不知道它是什么形状｡
‫好吧, 我知道了
‫这就是为什么我们需要那些从形状继承并实现功能的类｡
‫现在我可以创建一个构造函数, 公共球面, 一个双半径.
‫所以我们需要一个半径, 然后我们可以继续设置球体的名称, 应该是sphere,
‫我们应该有一个半径属性值｡
‫因此, 我们将传递给我们的半径指定为属性radius值｡
‫好了, 现在我们有了, 我们可以计算体积｡
‫所以现在不抛出异常, 我想计算球体的体积｡
‫为了达到这个目的, 我需要π, 我需要下面的计算｡
‫所以计算出半径的三次方, 然后乘以三除以四除以三｡
‫好吧, 我会的
‫这就是我们计算容量的方法, 现在我们可以继续执行get info方法｡
‫所以我要从我的立方体中复制信息｡
‫我要偷懒了｡
‫所以复制这部分并实现同样的东西｡
‫所以我们再次使用override关键字, 它的名字和在shape类中的名字完全一样｡
‫我们在这里使用基本代码信息来调用这里的任何方法｡
‫不管方法体是什么, 我们不传递长度, 也不讨论长度,
‫而是讨论半径和立方体.
‫在这个例子中, 它是一个半径为的球体｡
‫好吧, 我会的
‫现在我们已经有了所有这些, 我们现在可以做的是继续创建所有这些不同类的对象｡
‫所以我不打算在这里跟世界打招呼｡
‫相反, 我将创建一组形状｡
‫所以我会说, 好的, 请给予我一个数组的形状｡
‫它将是一个半径为4的新球体和一个半径为3的新立方体｡
‫在这个例子中, 实际上, 它的长度是3, 因为立方体没有半径, 它有长度｡
‫然后我想对每个形状执行一些操作｡
‫所以对于形状中的形状, 我想｡
‫在这种情况下, 把所有的都检查一遍, 就他们两个｡
‫但我想拥有的是塑造信息｡
‫所以get info应该被调用, 我想写这样的东西｡
‫在这种情况下, 零｡
‫将名称和然后我要显示的卷｡
‫所以我想有名字有卷的｡
‫然后, 当然, 我想知道我们正在看的这一部分的体积｡
‫因此, 塑造名字和塑造体积｡
‫所以这里我们调用体积法是很重要的, 对吧？
‫这不只是一个｡
‫财产｡
‫所以我们控制台上的红线有一个卷在这个例子里名字有一个卷的卷｡
‫所以它只会计算体积｡
‫好了, 现在我们来测试一下｡
‫让我们看看这里发生了什么, 我们创造了什么, 我们是什么, 所以这里有一个空行｡
‫然后它说, 这是一个球体｡
‫球体的半径为4｡
‫球体的体积为268｡ 08.
‫这是一个立方体｡
‫这个立方体的长度为3｡
‫立方体的体积为27｡
‫好吧, 我会的
‫你可以看到, 这是我们写的一段非常简单的代码, 但它已经解释或展示了我们需要了解的关于抽象类的大部分功能｡
‫现在, 很酷的事情是, 我们还可以使用一些我们还没有使用过的关键词｡
‫由于这段视频已经够长了, 我想我们在下一段视频中这样做｡
‫那到时见｡