问题描述
abstract class ServerMock(param: String) {
protected var someVar = params + "123"
fun justMyVar() = someVar
}
用法示例:
class BaseServer(param: String) : ServerMock(param) {
val y = someVar
}
这个类可以标记为open
而不是abstract
吗?
open
和 abstract
类有什么区别?
解决方法
abstract
类无法实例化,必须继承,抽象类默认为 open
用于扩展。类上的 open
修饰符允许继承它。如果类没有 open
修饰符,它被认为是 final 并且不能被继承。
您不能实例化 abstract
类。您需要使用 object
子类化或创建匿名类。在 abstract
类中,您可以只声明函数而不实现它们(强制子类实现它们)或提供默认实现。
abstract class BaseClass {
fun foo() // subclasses must implement foo
fun bar(): String = "bar" // default implementation,subclasses can,but does not have to override bar
}
// error: can not create an instance of an abstract class
val baseClass = BaseClass()
class SubClass : BaseClass {
// must implement foo
override fun foo() {
// ...
}
// can,but does not need to override bar
}
// declaring an anonymous class (having no name) using object keyword
val baseClass: BaseClass = object : BaseClass {
// must implement foo
override fun foo() {
// ...
}
// it is optional implementing bar
override fun bar(): String {
return "somethingElse"
}
}
既不是 abstract
也不是 open
的类被认为是最终的,不能扩展。
如果你想允许子类化,你应该把它标记为打开。
class AClass
// error: This type is final,so it can not be inherrited from.
class BClass : AClass
open class CClass
class DClass : CClass
所以如果你想允许 BaseServer
被子类化,你应该把它标记为 open
。如果您还想声明函数,但强制子类实现它们,您可以将 open
替换为 abstract
。
文档
,假设你有 2 个班级
- 班级人 [父班级]
- 类编码器 [子/子类]
当你想从 Person 继承 Coder 时,你必须让 Person open,所以它是可用的继承。 同时,您可以从人物本身制作对象。
当您不需要从父类创建对象(在我们的例子中是 Person)或者您看不到从它创建对象的任何意义时,您可以使用 abstract 而不是 open。
它的工作方式与 open 相同。但主要区别在于您不能再从 Person(父类)创建对象。