Java 17 的 sealed 的使用场景是什么呢?

红薯 发布于 2021/12/10 21:38
阅读 1K+
收藏 0

Java 17 sealed class 已经转正了,可是这个特性主要用于什么场景呢??

加载中
0
janz0912
janz0912

开这个特性,不如多重继承。我现在都管不住自己两个儿子,累死了。。

0
二次元萌控森
二次元萌控森

Java:你可以不用,但是我必须要有,叉腰。

0
随风巽
随风巽

限定子类,以后可用于模式匹配,与kotlin的密封类作用类似吧

0
ArchitectureMaster
ArchitectureMaster

sealed有一个非常有用的功能就是限定当前类为一个密封类无法被子类的方法所重写。

简单来讲就是你写了一个超类或基类里面封装了一些基础方法,别人可以用,但不想别人去重写这个方法。因为你的父类方法在没有sealed的情况无法避免被子类override重写。这时你可以将你的父类加上sealed前缀,将其声明为密封类,这样别人还是可以用,但无法通过重写来修改同样的方法名称。

打比方有A类func方法,B类继承了A类,并可以重写A类的func方法。C类使用B类就可以调用实际是A类的设计者设计的func方法。但如果B类重写了这个方法,那C类实际调用的是B重写的方法。这是A的设计者不愿见的事情,这时A的设计者想其它通过继承的类无法重写自己的func方法,这时就需要用到sealed方法,而这个特点在工作中非常常见!

举个现实中的例子,张三发表了一篇文章,李四可以通过继承拿来用,但这时李四把文章的内容改了(重写)还打着张三的名义,这时如果文章改得不好,李四没什么,张三就可能被骂,张三想通过方法只让别人引用自己原文,而不能修改这时就可以使用sealed。

ArchitectureMaster
ArchitectureMaster
回复 @ArchitectureMaster : 你说的是方法,我说的是意图。也就是你用final传达的意思不够直接。final给人的意义是多重。而使用sealed对类修饰,表明当前类的设计是遵守里氏替代原则!因为java里没有virtual关键字,java所有方法成员都可被override,这时sealed的作用就更明确。因为在其它语言是可以显示选读此方法被重写或不能的!
墨盒
墨盒
回复 @ArchitectureMaster : 你final加方法上就是啊
ArchitectureMaster
ArchitectureMaster
回复 @墨盒 : final不行的,final是不容许被继承!如果容许被继承,但不容许被重写就需要sealed了,final和sealed应用的场景是不同的。solid设计原则中有一个非常重要的原则就是里氏替代原则。就是子类的方法被重写后导致共有方法出现差别,这里就可以用sealed。而不可能使用final!final是一个不会被继承的类,而sealed可被继承但不能被重写,差别很大!
墨盒
墨盒
回复 @chowsanity : 我看得很清楚
chowsanity
chowsanity
回复 @墨盒 : 看清楚别人说的啥再评论行么???
下一页
0
ArchitectureMaster
ArchitectureMaster

六大设计原则通常指SOLID+迪米特法则,这其中非常重要的设计原则就是里氏替代原则,这个原则讲的是一个超类中的共用方法,不能被其它子类重写!在日常工作中,如果两个类都需要一个同样的方法,我们的做法可能会设计一个超类,这两个类都会继承这个类,但是如果说有一个子类重写了这个共有的方法,那这个子类在实现的时候得到的结果和超类的原有方法会不同。而这样就不符合里氏替代原则了,这时sealed类的密封原则阻止了子类override行为,就维护了里氏替代原则不会被违反。所以说sealed这个关键字的设计是有意义的!

ArchitectureMaster
ArchitectureMaster
回复 @一知先生 : 请阁下注意题主说的是sealed的场景,首先应用前提是父类有一个公共方法,是所有子类必须使用而不能被某个子类改变而发生改变的方法。并不是说子类没有重写父类方法后不一致的权力!子类方法有自己的实现返回不同的结果很正常。但有一种情况是公共方法必须保持一致性。如两个类中有一样的方法,这时可抽象到基类中,但如果没有sealed这时某个子类去重写了这个方法导致基类和子类方法返回结果不同
一知先生
一知先生
所以,从里氏替换原则原则来看待sealed关键字的设计目的是不正确的方向。
一知先生
一知先生
从这两个比较权威的说法中,并没有你所说的不允许重写的说法。 单纯从面向对象的角度来说,每一个对象由属性和行为构成,那么,子类可以替换父类,无非就是行为可以替换,但没有强制要求行为的结果也要一致,例如,getName结果,父类name为A.D, 子类为B.D,那么,结果不一致,是否是违反里氏替换原则? 里氏替换原则原则而,本意应该是强调方法名,参数,返回类型一致,重写就已经增加了这些限制。
一知先生
一知先生
另一种关于里氏替换原则的描述为Robert Martin在《敏捷软件开发:原则、模式与实践》一书中对原论文的解读:子类型(subtype)必须能够替换掉他们的基类型(base type)
一知先生
一知先生
里氏替换原则在1994年Barbara Liskov 和 Jeannette Wing发表论文中的描述是: If S is a declared subtype of T, objects of type S should behave as objects of type T are expected to behave, if they are treated as objects of t.
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部