用面向对象方法实现求圆和椭圆的周长与面积

  设最底层的基类为Shape,Shape有周长和面积,圆Circle和椭圆Ellipse继承于Shape,设置计算周长的接口为circum(),计算面积的接口为area()。继承图表如下:

这里写图片描述
图(1) Shape、Circle和Ellipse之间的继承图表

  用R语言里的S4结构,可以很方便地实现接口和继承,详细代码如下:
  //S4.R  

# part1 -------------------------------------------------------------------
##定义基类Shape
setClass("Shape",slots = list(name="character"))

##定义圆形类Circle,继承Shape
setClass("Circle",contains = "Shape",slots = list(radius="numeric"),
         prototype = list(radius=1))
##验证radius大于0
setValidity("Circle",function(object){
    if(object@radius <= 0) stop("Radius is negative")
})

##定义计算面积的接口
setGeneric("area",function(obj,...) standardGeneric("area"))

##实现面积接口
setMethod("area","Circle",function(obj,...){
    print("Area Circle Method")  
    pi * obj@radius^2
})


##定义周长的接口
setGeneric("circum",function(obj,...) standardGeneric("circum"))

##实现周长接口
setMethod("circum","Circle",function(obj,...){
    2 * pi *obj@radius
})


##创建两个圆的实例---------------#
c1 <- new("Circle",name="c1")
c2 <- new("Circle",name="c2",radius=5)
# c1; c2

##计算两个圆的面积
area(c1)
area(c2)

##计算两个圆的周长
circum(c1)
circum(c2)


# part2 -------------------------------------------------------------------
##定义椭圆类Ellipse, 继承Shape
setClass("Ellipse",contains = "Shape",slots = list(radius="numeric"),
         prototype = list(radius = c(1,1)))

##验证椭圆的半径
setValidity("Ellipse",function(object) {
  if (length(object@radius) != 2 ) stop("It's not Ellipse.")
  if (length(which(object@radius<=0))>0) stop("Radius is negative.")
})

##计算椭圆的面积
setMethod("area","Ellipse",function(obj,...){
  print("Area Ellipse Method")  
  pi * prod(obj@radius)
})

##计算椭圆的周长
setMethod("circum","Ellipse",function(obj,...){
  cat("Ellipse Circum: \n")  
  2*pi * sqrt((obj@radius[1]^2 + obj@radius[2]^2)/2 )
})


##创建椭圆的两个实例---------------------#
e1 <- new("Ellipse",name="e1"); 
e2 <- new("Ellipse",name="e2",radius=c(5,1))


##计算两个椭圆的面积
area(e1)
area(e2)

##计算两个椭圆的周长
circum(e1)
circum(e2)

  效果如下:

这里写图片描述
图(2) 求周长与面积

  方法二:当椭圆的长半径和短半径相等时,radius的两个值相等,形成的图形为圆形。利用这个特点,我们就可以重新设计圆与椭圆的关系。即椭圆是圆的父类,圆就是椭圆的子类。代码如下:
  //S4a.R  


# part1 -------------------------------------------------------------------
##面向对象
##Shape --> Ellipse -->Circle
##定义基类Shape
setClass("Shape",slots = list(name="character",shape="character"))
##定义获取图形的种类接口
setGeneric("getShape",function(obj,...) standardGeneric("getShape"))
##实现获取图形的种类接口
setMethod("getShape","Shape",function(obj,...){
    cat(obj@shape,"\n")
})


##定义椭圆类Ellipse,继承Shape
setClass("Ellipse", contains = "Shape",slots = list(radius="numeric"),
         prototype = list(radius=c(1,1),shape="Ellipse"))
##定义圆形Circle, 继承Ellipse
setClass("Circle",contains = "Ellipse",slots = list(radius="numeric"),
         prototype = list(radius=1, shape="Circle"))

##定义area接口
setGeneric("area",function(obj,...) standardGeneric("area"))
##定义circum接口
setGeneric("circum",function(obj,...) standardGeneric("circum"))

##area接口的Ellipse实现
setMethod("area","Ellipse",function(obj,...){
    cat("Ellipse Area: \n")
    pi*prod(obj@radius)
})

##area接口的Circle实现
setMethod("area","Circle",function(obj,...){
    cat("Circle Area: \n")  
    pi*obj@radius^2
})


##circum接口的Ellipse实现
setMethod("circum","Ellipse",function(obj,...){
    cat("Ellipse Circum: \n")
    2*pi*sqrt((obj@radius[1]^2 + obj@radius[2]^2)/2)
})

##circum接口的Circle实现
setMethod("circum","Circle",function(obj,...){
    cat("Circle circum: \n")
    2*pi*obj@radius
})

##创建实例
e1 <- new("Ellipse",name="e1",radius=c(2,5))
c1 <- new("Circle",name="c1",radius=2)

##计算面积
area(e1)
area(c1)

##计算周长
circum(e1)
circum(c1)

##获取图形的类型
getShape(e1)
getShape(c1)
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值