Scala泛型foreach中访问Chat子类公共name字段问题
解决Scala泛型方法中访问子类共有name字段的问题
首先,问题的核心在于你的Chat类并没有将构造参数name暴露为可公共访问的成员——Scala中构造参数默认是private的,除非你用val或var修饰它,否则外部(包括你的泛型方法)无法直接访问这个值。
第一步:修改基类,暴露name字段
先把Chat类的构造参数改为val,这样所有继承自Chat的子类(Siamois、BébéSiamois)都会自动继承这个可访问的name成员:
trait Animal {} class Chat(val name: String) extends Animal { def this() = this("Chat sans nom") } class Siamois(name: String) extends Chat(name) { def this() = this("Siamois sans nom") } class BébéSiamois(name: String) extends Siamois(name) { def this() = this("Bébé Siamois sans nom") } val chat1: Chat = new Chat("Darius") val chat2: Siamois = new Siamois("Iroise") val chat3: BébéSiamois = new BébéSiamois("Jazz") val chat4: Siamois = new BébéSiamois("Enzo") val chat5: BébéSiamois = new BébéSiamois("Elios") val listeFelins = List(chat2, chat3, chat4, chat5)
第二步:修改泛型方法,访问name字段
现在你的泛型方法就可以直接在foreach中访问每个实例的name了:
def createAListeOfSiamoisAndChild[T <: Siamois](xs: List[T]): Unit = { xs.foreach(felin => println(f"Felins: ${felin.name}")) }
可选:更灵活的抽象方式(用Trait约束)
如果你想让代码更具扩展性,可以定义一个Named trait来抽象"拥有name"的行为,让相关类实现它:
trait Named { def name: String } trait Animal {} class Chat(val name: String) extends Animal with Named { def this() = this("Chat sans nom") } class Siamois(name: String) extends Chat(name) with Named { def this() = this("Siamois sans nom") } class BébéSiamois(name: String) extends Siamois(name) with Named { def this() = this("Bébé Siamois sans nom") } // 泛型方法可以用Named约束,支持所有实现了Named的类型 def createAListeOfNamedFelins[T <: Siamois with Named](xs: List[T]): Unit = { xs.foreach(felin => println(f"Felins: ${felin.name}")) }
这样不管后续新增多少子类,只要继承了Chat(或者直接实现Named),都能在泛型方法中访问name字段。
内容的提问来源于stack exchange,提问作者uknys
相关产品推荐
相关产品推荐

