我想设置来自String的Html电子邮件的主体,而不是为升级邮件程序设置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))
为什么会发生这种情况?如何正确修复?
我更改了导入Mailer._以导入HtmlMailer._并且它有效,但我相信它打破了Liskov替换原则,因为我无法替换HtmlMailer
而不是Mailer
,因为它们具有不同的参数类型?
答案 0 :(得分:1)
您遇到路径依赖类型和单身人士的问题。当您有嵌套类时,外部类的每个实例都有一个不同的嵌套类实例。
现在,From
(加Subject
,To
等),因为它们是嵌套的,属于特定实例。在这种情况下,您有两个实例提供它们。它们是对象:
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.Mailer
的任何其他实例替换net.liftweb.util.Mailer
,这样就可以了。你不能使用net.liftweb.util.Mailer
的两个不同实例,即使它们都属于同一类。