开放类和抽象类有什么区别?

11
abstract class ServerMock(param: String) {
   protected var someVar = params + "123"

   fun justMyVar() = someVar
}

用法示例:

class BaseServer(param: String) : ServerMock(param) {
   val y = someVar
}

这个类能被标记为 open 而不是 abstract 吗?

openabstract 类之间有什么区别?


7
简短回答:open 可以被创建子类,abstract 必须被创建子类。子类化一个 abstract 类可能需要实现一些方法,而一个 open 类可以直接被创建子类而不需要修改,因为它可以被独立实例化。 - CryptoFool
3个回答

25

抽象类不能被实例化,必须被继承,抽象类默认是open的,可以被扩展。在类上使用open修饰符允许继承它。如果类没有open修饰符,则被认为是final的,不能被继承。


7

您不能实例化一个抽象类。您需要通过子类化或使用object创建一个匿名类。在抽象类中,您可以声明函数而不实现它们(强制子类实现它们),或者提供一个默认实现。

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"
  }
}

一个既不是抽象类也不是开放类的类被认为是最终类,不能被扩展。
如果你想允许子类化,你应该标记它为开放类。
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。如果你还想声明函数,但强制子类实现它们,可以用abstract替换open

文档


1
我感谢您的用心示例! - CryptoFool
1
抽象类相对于开放类的一个优势是,如果它实现了一个接口(或扩展另一个抽象类),则不需要自己实现所有必需的函数,这种情况下它会强制子类去实现。 - Pawel

3

假设你有两个类:

  1. Person类[父类]
  2. Coder类[子类]

当你想要从 Person 类继承 Coder 类时,你必须将 Person 设置为 open,这样它就可以被继承。 同时,你也可以从 Person 本身创建对象。

当你不需要从父类(在我们的例子中即为 Person)创建对象或者你看不到创建对象的意义时,可以使用 abstract 代替 open

它与 open 的工作方式相同。但主要区别在于你不能再从 Person (父类) 创建对象了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接