ASP.NET可交互式位图窗体设计2

我们的任务
  这个程序的基本思想如下:我们有一个 abstract 基类(在 Microsoft Visual
Basic? 中是 MustInherit),其中包含公共数据(如边框)和一套虚拟方法,虚拟方法
多数是抽象的(在 Visual Basic 中是 MustOverride),例如 Draw。请注意,Draw 的
多态性很重要,因为每个可绘制对象类型(如点、线、矩形、圆等)都是用完全不同的
代码绘制的。

  虽然方法可以是多态的,但数据不能。因此,我们只将确实应用于所有可能的可绘
制对象的数据放在程序中 -- 在本例中,放置了一个边框和颜色(在其中绘制对象的线
)。

  与特定类型的可绘制对象相关的数据(例如圆的中心和半径、矩形相对点的坐标,
或者一条线的端点)都应该在与该类型的可绘制对象对应的特定类(从抽象基类中派生
)中声明。请注意,可以使用二次派生合并相似的对象。例如,可以从椭圆中派生出圆
,因为所有的圆都是椭圆。与此类似,也可以从矩形中派生出方形,因为所有的方形都
是矩形(也都是四边形、多边形)。所选择的派生树会反映类之间的关系,以及常用的
预期使用模式,这样您经常执行的操作便会非常快速、方便。

  以下是我们的类派生图:



图 3:类派生图

  因为构造函数(在 Visual Basic 中为 New)存在的主要原因是用于初始化数据,
因此构造函数不是(实际上也不能是)多态的。这意味着初始创建操作不能是多态的,
因为数据要求随类型的不同而不同。但是,一个好的设计在对象创建后,可在之后的使
用中将对象作为多态处理,这里我们就是这样做的。

  让我们看看这个类集中包含什么,从根抽象基类开始:

  抽象 (MustInherit) 基类
  以下是 C# 中抽象基类的代码。单击此处在新窗口中查看全部源文件。



  C#

public abstract class DShape {
public abstract void Draw(Graphics g);
protected Rectangle bounding;
protected Color penColor; // 还应具有属性
// 还应具有移动、调整大小等方法。
}

  以下是等同的 Visual Basic .NET 代码。单击此处在新窗口中查看全部源文件。

  Visual Basic .NET

Public MustInherit Class DShape
Public MustOverride Sub Draw(ByVal g As Graphics)
Protected bounding As Rectangle
Protected penColor As Color ' 还应具有属性
' 还应具有移动、调整大小等方法。
End Class

  语法虽然不同,但很明显这是相同的类。

  请注意,Draw 方法被暗示为 virtual (Overridable),因为它被声明为
abstract (MustOverride)。还要注意在这个类中我们并没有提供一个实现。因为我们尚
不知道在这个类中执行的对象,因此不可能写出绘图代码。

  包含哪些数据?
  另请注意,这里并没有很多数据 -- 但我们已经为这样一个抽象类声明了所有数据


  每一个可绘制对象(无论其形状如何)都有一个边框 -- 即可以完全包含该对象的
最小可能矩形。边框用于绘制点(作为很小的矩形)、长方形和圆 -- 并且对于其他形
状,可以作为第一个用于点击或碰撞测试的快速估计。

  适用于所有对象的其他共同点并没有很多;中心对于某些对象有用,例如圆和长方
形,对于其他对象(如三角形)则没有意义。并且通常都是使用角来表示矩形,而不是
使用中心。但您不能使用角来指定圆,因为圆没有角。Dr. GUI 确信您已经看到了为一
个普通可绘制对象指定其他数据的困难之处。

  每个可绘制对象还有一个与绘制它的线相关联的颜色,这里我们也做了声明。

  某些派生类
  如上所述,我们不能真正创建一个抽象基类类型的对象,虽然我们可以将从抽象基
类(或任何基类)中派生的任何对象作为基类对象处理。

  所以,为创建一个绘图对象,我们必须从抽象基类中派生一个新类 -- 并确保覆盖
所有 abstract/MustOverride 方法。

  在本例中我们将使用 DHollowCircle 类。DHollowRectangle 类和 DPoint 类非常
相似。

  以下是 C# 中的 DHollowCircle。单击此处在新窗口中查看其他类。


  C#
public class DHollowCircle : DShape
{
public DHollowCircle(Point p, int radius, Color penColor) {
p.Offset(-radius, -radius); // 需要转换到左上角
int diameter = radius * 2;
bounding = new Rectangle(p, new Size(diameter, diameter));
this.penColor = penColor;
}

public override void Draw(Graphics g) {
using (Pen p = new Pen(penColor)) {
g.DrawEllipse(p, bounding);
}
}
}


以下是等同的 Visual Basic .NET 类。单击此处在新窗口中查看其他类。


Visual Basic .NET
Public Class DHollowCircle
Inherits DShape

Public Sub New(ByVal p As Point, ByVal radius As Integer, _
ByVal penColor As Color)
p.Offset(-radius, -radius) ' 需要转换到左上角
Dim diameter As Integer = radius * 2
bounding = New Rectangle(p, New Size(diameter, diameter))
Me.penColor = penColor
End Sub

Public Overrides Sub Draw(ByVal g As Graphics)
Dim p = New Pen(penColor)
Try
g.DrawEllipse(p, bounding)
Finally
p.Dispose()
End Try
End Sub
End Class


  请注意,我们没有为这个类声明其他数据 -- 它给出的边框和笔已经足够了。(对
于点和矩形是这样,但对于三角形和其他多边形就不够了。)我们的应用程序不需要在
设置圆后知道圆的中心或半径,因此将它们忽略掉。(如果需要中心和半径,我们可以
存储这些数据,或者根据边框计算得出。)

  但我们确实需要边框,因为它是用于绘制圆的 Graphics.DrawEllipse 方法的一个
参数。因此我们根据在构造函数中传递的中心点和半径计算边框。

  下面我们深入了解每一个方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值