0

我想从 String 设置 Html 电子邮件的正文,而不是 Lift Mailer 的 Xml 节点,所以我将 Mailer 子类化并重新定义了buildMailBody方法:

class HtmlMailer extends Mailer {
  final case class HtmlMailBodyType(text: String) extends MailBodyType

  override protected def buildMailBody(tab: MailBodyType) = {
    tab match {
      case HtmlMailBodyType(text) =>
        val bp = new MimeBodyPart
        bp.setText(text, charSet, "html")
        bp
      case _ => super.buildMailBody(tab)
    }
  }
}

object HtmlMailer extends HtmlMailer

当我尝试使用它时:

import net.liftweb.util.Mailer
import Mailer._    

HtmlMailer.sendMail(From(sender.email), Subject(subject), To(user.email), HtmlMailBodyType(body))

我得到编译错误:

error: type mismatch;
found   : net.liftweb.util.Mailer.From
required: com.mypackage.HtmlMailer.From
Error occurred in an application involving default arguments.
HtmlMailer.sendMail(From(sender.email), Subject(subject), To(user.email), HtmlMailBodyType(body))

为什么会发生这种情况,我该如何正确解决?

我将 import Mailer._ 更改为 import HtmlMailer._ 并且它有效,但我相信它违反了 Liskov 替换原则,因为我不能替换HtmlMailerMailer因为它们有不同的参数类型?

4

1 回答 1

1

您在使用路径相关类型和单例时遇到问题。当您有嵌套类时,外部类的每个实例都有嵌套类的不同实例。

现在,From(plus Subject, To, etc),因为它们是嵌套的,属于一个特定的实例。在这种情况下,您有两个实例提供它们。它们是对象

net.liftweb.util.Mailer
com.mypackage.HtmlMailer

请注意,这些不是,它们是对象

现在,该方法sendMail要求其参数由与自身属于同一实例的类组成。提出这样的要求有很多原因,因为有很多方法可以不提出。

所以,真的,这里没有违反 liskov 替换原则,只是违反了导入隐藏的类型。如果你明确地写出来,它会变得更清楚:

val myInst: net.liftweb.util.Mailer = HtmlMailer
myInst.sendMail(myInst.From(sender.email), myInst.Subject(subject), myInst.To(user.email), myInst.HtmlMailBodyType(body))

您可以用或任何其他实例替换HtmlMailer那里,它会起作用。您不能使用 的两个不同实例,即使它们都属于同一类。net.liftweb.util.Mailernet.liftweb.util.Mailernet.liftweb.util.Mailer

于 2012-06-20T17:19:53.640 回答