【问题标题】:What is the difference between 'open' and 'public' in Kotlin?Kotlin 中的“开放”和“公开”有什么区别?
【发布时间】:2018-08-08 00:23:48
【问题描述】:

我是 Kotlin 的新手,我对 openpublic 关键字感到困惑。谁能告诉我这些关键字之间的区别?

【问题讨论】:

标签: kotlin keyword public


【解决方案1】:

open 关键字的意思是“开放扩展”:

上的open注解与Java的final相反:它允许其他人从这个类继承。 默认,Kotlin 中的所有类都是final,这对应于Effective Java,Item 17:Design and document for inheritance or else 禁止

您还需要明确说明要使其可覆盖的方法,也标有open

open class Base {
    open fun v() {}
    fun nv() {}
}

public 关键字充当可见性修饰符,可应用于类、函数等。 请注意,如果没有明确指定其他内容,public 是默认值:

如果您不指定任何可见性修饰符,则默认使用public,这意味着您的声明将在任何地方可见

【讨论】:

  • “您的声明将随处可见”是什么意思?
  • 这是来自文档的引用,任何类都可以访问并可以创建实例:kotlinlang.org/docs/reference/visibility-modifiers.html
  • 好的。现在我懂了。 “可见”是指“可访问”。并且public 可以从任何地方访问它。 open 允许继承类。谢谢!
【解决方案2】:

Java 中的class A { ... } 等于 Kotlin 中的 open class A { ... }
Java 中的final class B { ... } 等于 Kotlin 中的 class B { ...}

public无关。

在 Kotlin 中,没有访问修饰符的所有内容默认为 public。你可以在定义中明确的说public,但在Kotlin中不是必须的。

所以,

public class A { ... }

class A { ... }

在 Kotlin 中是相同的。

【讨论】:

  • 如果是这样,创建一个类public到底有什么用?如果使用open,则可以继承该类。制作类public的主要目的是什么?
  • 我认为它就像 Kotlin 中的分号。它们是为 Java 人而存在的。
【解决方案3】:

我放在这里只是为了我的备忘录,也许对其他人有用:

open kotlin 中的类意味着一个类可以被继承,因为默认情况下它们不是:

 class Car{....}
 class Supercar:Car{....} : // give an error

 open Car2{....}
 class Supercar:Car2{....} : // ok
Java中的

public类是关于类的可见性(与继承无关:除非Java中的类是final的,否则默认可以继承)。 在 kotlin 中,所有的类默认都是公开的。

kotlin 中的

open 方法意味着该方法可以被覆盖,因为默认情况下它们不是。 相反,在 Java 中,所有方法都可以默认被覆盖

open 类的方法默认情况下不能像往常一样被覆盖(不管类是否打开),必须声明它们可以被覆盖:

 open class Car{
    fun steering{...}
 }
 class Supercar:Car{
    override fun steering {...}  // give an error
 } 

 open class Car2{
    open fun steering{...}
 }
 class Supercar:Car2{
    override fun steering {...}  // ok
 }

更多详情:https://kotlinlang.org/docs/reference/classes.html

【讨论】:

    【解决方案4】:

    public:Kotlin 中的 public 关键字类似于 java,用于使类、方法、变量的可见性可以从任何地方访问。

    open:在 Kotlin 中所有的类、函数和变量默认都是 final 的,通过继承属性,我们不能继承 final 类、final 函数和数据成员的属性。所以我们在类或函数或变量之前使用 open 关键字来使其可继承。

    【讨论】:

    • 这是错误的,你仍然可以继承可见的非open 成员但是你不能覆盖它。
    • 请访问以下 Kotlin 官网链接以消除您的疑问。 kotlinlang.org/docs/…
    【解决方案5】:

    open 与 java 中的 Final 相反。 如果类不是“开放的”,则不能被继承。

    class First{}
    class Second:First(){}  // Not allowed. Since 'First' is Final(as in Java) by default. Unless marked "open" it can't be inherited 
    

    不要混淆公开和公开。 public 是可见性修饰符

    class Third{}  // By default this is public
    private class Fourth{}
    class Fifth{
        val third = Third() // No issues
        val fourth = Fourth() // Can't access because Fourth is private
    }
    

    【讨论】:

      【解决方案6】:

      公开 VS 最终 VS 公开

      打开:

      1. 子类可以访问它,因为它们是由其父类继承的。
      2. 在 Kotlin 中你需要添加 'open' 关键字,这与默认情况下所有类都是 'open' 的 java 不同 示例:
      1. Kotlin:公开 A 类 () {}
      2. Java:A 类 () {}

      最终:

      1. 子类无法访问或继承。
      2. 在 JAVA 中你需要添加 'final' 关键字,这与 kotlin 的所有类默认都是 'final' 不同 示例:
      1. Kotlin:A 类 () {}
      2. Java:最终类 A () {}

      PUBLIC : 任何类,无论其继承与否,都可以访问其数据或方法。

      Kotlin 中的示例:

      //Final
      class DemoA() {
          
          protected fun Method() {
      
          }
      
      }
      
      class DemoB() : DemoA {
          Method() // can't access
      }
      
      //OPEN
      open class DemoA() {
          
          protected fun Method() {
      
          }
      
      }
      
      class DemoB() : DemoA {
          Method() // can access
      }
      
      //Public
      class DemoA() {
      
          fun Method() {
      
          }
      
      }
      
      class DemoB()  {
          val a = DemoA()
          a.Method() // can access
      }
      

      Java 示例:

      //FINAL
      final class DemoA() {
          protected void name() {
              
          }
      }
      
      class DemoB() extends DemoA {
          name(); // Can't access
      }
      
      //Open
      class DemoA() {
          protected void name() {
              
          }
      }
      
      class DemoB() extends DemoA {
          name(); // Can access
      }
      
      //Public
      class DemoA() {
          void name() {
              
          }
      }
      
      class DemoB(){
          DemoA a = new DemoA()
          a.name(); // Can access
      }
      

      【讨论】:

        【解决方案7】:

        所有classesmethodsmembers默认都是public,但不是open

        kotlin 中的关键字open 表示“开放扩展”

        表示如果您希望任何类成为 inherited 任何子类或 method 在子类中被覆盖,您必须标记为 open 否则您将收到编译时错误

        注意:abstract 类或方法默认为open,您无需显式添加。

        【讨论】:

          猜你喜欢
          • 2014-04-02
          • 2012-05-28
          • 2014-08-29
          • 2018-12-22
          • 2014-01-12
          • 2011-07-25
          • 2019-08-19
          相关资源
          最近更新 更多